diff options
Diffstat (limited to 'libcxx')
487 files changed, 10362 insertions, 8037 deletions
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index a119850..8b4cd26 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -66,6 +66,19 @@ if (NOT "${LIBCXX_HARDENING_MODE}" IN_LIST LIBCXX_SUPPORTED_HARDENING_MODES) message(FATAL_ERROR "Unsupported hardening mode: '${LIBCXX_HARDENING_MODE}'. Supported values are ${LIBCXX_SUPPORTED_HARDENING_MODES}.") endif() +set(LIBCXX_SUPPORTED_ASSERTION_SEMANTICS hardening_dependent ignore observe quick_enforce enforce) +set(LIBCXX_ASSERTION_SEMANTIC "hardening_dependent" CACHE STRING + "Specify the default assertion semantic to use. This semantic will be used + inside the compiled library and will be the default when compiling user code. + Note that users can override this setting in their own code. This does not + affect the ABI. Supported values are ${LIBCXX_SUPPORTED_ASSERTION_SEMANTICS}. + `hardening_dependent` is a special value that instructs the library to select + the assertion semantic based on the hardening mode in effect.") + +if (NOT "${LIBCXX_ASSERTION_SEMANTIC}" IN_LIST LIBCXX_SUPPORTED_ASSERTION_SEMANTICS) + message(FATAL_ERROR + "Unsupported assertion semantic: '${LIBCXX_ASSERTION_SEMANTIC}'. Supported values are ${LIBCXX_SUPPORTED_ASSERTION_SEMANTICS}.") +endif() set(LIBCXX_ASSERTION_HANDLER_FILE "vendor/llvm/default_assertion_handler.in" CACHE STRING @@ -750,6 +763,18 @@ config_define(${LIBCXX_ENABLE_WIDE_CHARACTERS} _LIBCPP_HAS_WIDE_CHARACTERS) config_define(${LIBCXX_ENABLE_TIME_ZONE_DATABASE} _LIBCPP_HAS_TIME_ZONE_DATABASE) config_define(${LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS} _LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS) +# Set C library in use +if (RUNTIMES_USE_LIBC STREQUAL "picolibc") + config_define(1 _LIBCPP_LIBC_PICOLIBC) + # picolibc is derived from newlib and behaves the same in regards to libc++ + # so setting both here: + # * _LIBCPP_LIBC_NEWLIB is used now + # * _LIBCPP_LIBC_PICOLIBC can be used for further customizations later + config_define(1 _LIBCPP_LIBC_NEWLIB) +elseif (RUNTIMES_USE_LIBC STREQUAL "newlib") + config_define(1 _LIBCPP_LIBC_NEWLIB) +endif() + # TODO: Remove in LLVM 21. We're leaving an error to make this fail explicitly. if (LIBCXX_ENABLE_ASSERTIONS) message(FATAL_ERROR "LIBCXX_ENABLE_ASSERTIONS has been removed. Please use LIBCXX_HARDENING_MODE instead.") @@ -763,6 +788,17 @@ elseif (LIBCXX_HARDENING_MODE STREQUAL "extensive") elseif (LIBCXX_HARDENING_MODE STREQUAL "debug") config_define(8 _LIBCPP_HARDENING_MODE_DEFAULT) endif() +if (LIBCXX_ASSERTION_SEMANTIC STREQUAL "hardening_dependent") + config_define(2 _LIBCPP_ASSERTION_SEMANTIC_DEFAULT) +elseif (LIBCXX_ASSERTION_SEMANTIC STREQUAL "ignore") + config_define(4 _LIBCPP_ASSERTION_SEMANTIC_DEFAULT) +elseif (LIBCXX_ASSERTION_SEMANTIC STREQUAL "observe") + config_define(8 _LIBCPP_ASSERTION_SEMANTIC_DEFAULT) +elseif (LIBCXX_ASSERTION_SEMANTIC STREQUAL "quick_enforce") + config_define(16 _LIBCPP_ASSERTION_SEMANTIC_DEFAULT) +elseif (LIBCXX_ASSERTION_SEMANTIC STREQUAL "enforce") + config_define(32 _LIBCPP_ASSERTION_SEMANTIC_DEFAULT) +endif() if (LIBCXX_PSTL_BACKEND STREQUAL "serial") config_define(1 _LIBCPP_PSTL_BACKEND_SERIAL) diff --git a/libcxx/docs/ABIGuarantees.rst b/libcxx/docs/ABIGuarantees.rst index 4d4674c..e680f54 100644 --- a/libcxx/docs/ABIGuarantees.rst +++ b/libcxx/docs/ABIGuarantees.rst @@ -205,6 +205,16 @@ This flag fixes the implementation of CityHash used for ``hash<fundamental-type> CityHash has the problem that it drops some bits on the floor. Fixing the implementation changes the hash of values, resulting in an ABI break. +``_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE`` +------------------------------------------ +This flag changes the implementation of ``atomic::wait()`` and ``atomic::notify_one()/notify_all()`` to use the +native atomic wait/notify operations on platforms that support them based on the size of the atomic type, instead +of the type itself. This means for example that a type with ``sizeof(T) == 4`` on Linux that doesn't have padding +bytes would be able to use the underlying platform's atomic wait primitive, which is otherwise only used for ``int32_t``. +Since the whole program must use the same implementation for correctness, changing this is an ABI break since libc++ +supports linking against TUs that were compiled against older versions of the library. + + inline namespaces ================= Inline namespaces which contain types that are observable by the user need to be kept the same, since they affect diff --git a/libcxx/docs/AddingNewCIJobs.rst b/libcxx/docs/AddingNewCIJobs.rst index 9d749c0..7a12728 100644 --- a/libcxx/docs/AddingNewCIJobs.rst +++ b/libcxx/docs/AddingNewCIJobs.rst @@ -28,6 +28,9 @@ An example of a job definition is: - label: "C++11" command: "libcxx/utils/ci/run-buildbot generic-cxx11" + env: + CC: clang + CXX: clang++ artifact_paths: - "**/test-results.xml" agents: diff --git a/libcxx/docs/Contributing.rst b/libcxx/docs/Contributing.rst index 4e9d1ba..e660dae 100644 --- a/libcxx/docs/Contributing.rst +++ b/libcxx/docs/Contributing.rst @@ -269,12 +269,12 @@ Updating the CI testing container images ---------------------------------------- The libcxx linux premerge testing can run on one of three sets of runner -groups. The three runner group names are "llvm-premerge-libcxx-runners", -"llvm-premerge-libcxx-release-runners" and "llvm-premerge-libcxx-next-runners". -Which runner set to use is controlled by the contents of +groups. The three runner group names are ``llvm-premerge-libcxx-runners``, +``llvm-premerge-libcxx-release-runners`` and ``llvm-premerge-libcxx-next-runners``. +The runner set to use is controlled by the contents of https://github.com/llvm/llvm-project/blob/main/.github/workflows/libcxx-build-and-test.yaml. -By default, it uses "llvm-premerge-libcxx-runners". To switch to one of the -other runner sets, just replace all uses of "llvm-premerge-libcxx-runners" in +By default, it uses ``llvm-premerge-libcxx-runners``. To switch to one of the +other runner sets, just replace all uses of ``llvm-premerge-libcxx-runners`` in the yaml file with the desired runner set. Which container image is used by these three runner sets is controlled @@ -282,7 +282,7 @@ and set by the variable values in https://github.com/llvm/llvm-zorg/blob/main/premerge/premerge_resources/variables.tf. The table below shows the variable names and the runner sets to which they correspond. To see their values, follow the -link above (to variables.tf in llvm-zorg). +link above (to ``variables.tf`` in llvm-zorg). +------------------------------------+---------------------------+ |Runner Set |Variable | @@ -295,39 +295,24 @@ link above (to variables.tf in llvm-zorg). +------------------------------------+---------------------------+ -When updating the container image you can either update just the -runner binary (the part the connects to Github), or you can update -everything (tools, etc.). Whether to update just the runner or to update -everything is controlled by the value of ``ACTIONS_BASE_IMAGE``, under -``actions-builder`` in ``libcxx/utils/ci/docker-compose.yml``. - -To update just the runner binary, change the value of ``ACTIONS_BASE_IMAGE`` -to be a modified version of one of the libcxx runner variable images from -https://github.com/llvm/llvm-zorg/blob/main/premerge/premerge_resources/variables.tf, -as follows: Find the libcxx runner image name you want to use from the -variables.tf file. The name will be something like -``ghcr.io/llvm/libcxx-linux-builder:<some-commit-SHA>``. Replace -``libcxx-linux-builder`` with ``libcxx-linux-builder-base``. Use this new image -name as the value you assign to ``ACTIONS_BASE_IMAGE``. - -To update the entire container image, set the value of ``ACTIONS_BASE_IMAGE`` -to ``builder-base``. If the value is already ``builder-base`` (there -have been no just-the-runner updates since the last complete update), then you -need to find the line containing ``RUN echo "Last forced update executed on`` -in ``libcxx/utils/ci/Dockerfile`` and update the date to be the current date. - -Once you have created and merged a PR with those changes, a new image -will be created, and a link to it can be found at -https://github.com/llvm/llvm-project/pkgs/container/libcxx-linux-builder, -where the actual image name should be -``ghcr.io/llvm/libcxx-linux-builder:<SHA-of-committed-change-from-PR>``. - -Lastly you need to create a PR in the llvm-zorg repository, -updating the the value of the appropriate libcxx runner variable in -the variables.tf file mentioned above to the name of your newly created -image (see above paragraph about finding the image name). Once that change -has been merged, an LLVM premerge maintainer (a Google employee) must use -terraform to apply the change to the running GKE cluster. +When updating the container image you can either update just the runner binary (the part +that connects to Github), or you can update everything (tools, etc.). To update the runner +binary, bump the value of ``GITHUB_RUNNER_VERSION`` in ``libcxx/utils/ci/docker/docker-compose.yml``. +To update all of the tools, bump ``BASE_IMAGE_VERSION`` to a newer version of the ``libcxx-linux-builder-base`` +image. You can see all versions of that image at https://github.com/llvm/llvm-project/pkgs/container/libcxx-linux-builder-base. + +On push to ``main``, a new version of both the ``libcxx-linux-builder`` and the ``libcxx-android-builder`` +images will be built and pushed to https://github.com/llvm/llvm-project/packages. + +You can then update the image used by the actual runners by changing the sha associated +to ``libcxx_runner_image``, ``libcxx_release_runner_image`` or ``libcxx_next_runner_image`` +in `the Terraform configuration file <https://github.com/llvm/llvm-zorg/blob/main/premerge/premerge_resources/variables.tf>`_. +To do so, you will need to create a PR in the llvm-zorg repository and wait for it to be +merged. Once that change has been merged, an LLVM premerge maintainer (a Google employee) +must use terraform to apply the change to the running GKE cluster. + +.. note:: When you update the ``libcxx_runner_image``, also make sure to update the + ``libcxx/utils/ci/run-buildbot-container`` script to contain the new image. Monitoring premerge testing performance diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst index d5ed918..756bdf7 100644 --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -486,6 +486,8 @@ Status ---------------------------------------------------------- ----------------- ``__cpp_lib_not_fn`` ``202306L`` ---------------------------------------------------------- ----------------- + ``__cpp_lib_optional`` ``202506L`` + ---------------------------------------------------------- ----------------- ``__cpp_lib_optional_range_support`` ``202406L`` ---------------------------------------------------------- ----------------- ``__cpp_lib_out_ptr`` ``202311L`` diff --git a/libcxx/docs/Hardening.rst b/libcxx/docs/Hardening.rst index 1cdb360..1360518 100644 --- a/libcxx/docs/Hardening.rst +++ b/libcxx/docs/Hardening.rst @@ -328,6 +328,20 @@ following options to the compiler: All the :ref:`same notes <notes-for-users>` apply to setting this macro as for setting ``_LIBCPP_HARDENING_MODE``. +Notes for vendors +----------------- + +Similarly to hardening modes, vendors can set the default assertion semantic by +providing ``LIBCXX_ASSERTION_SEMANTIC`` as a configuration option, with the +possible values of ``hardening_dependent``, ``ignore``, ``observe``, +``quick_enforce`` and ``enforce``. The default value is ``hardening_dependent`` +which is a special value that instructs the library to select the semantic based +on the hardening mode in effect (the mapping is described in +:ref:`the main section on assertion semantics <assertion-semantics>`). + +This option controls both the assertion semantic that the precompiled library is +built with and the default assertion semantic that users will build with. + .. _override-assertion-handler: Overriding the assertion failure handler @@ -447,6 +461,13 @@ The first character of an ABI tag encodes the hardening mode: - ``d`` -- [d]ebug mode; - ``n`` -- [n]one mode. +The second character of an ABI tag encodes the assertion semantic: + +- ``i`` -- [i]gnore semantic; +- ``o`` -- [o]bserve semantic; +- ``q`` -- [q]uick-enforce semantic; +- ``e`` -- [e]nforce semantic. + Hardened containers status ========================== diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst index a6a0ac8..9f1e3d5 100644 --- a/libcxx/docs/ReleaseNotes/22.rst +++ b/libcxx/docs/ReleaseNotes/22.rst @@ -40,6 +40,7 @@ Implemented Papers - P2321R2: ``zip`` (`Github <https://llvm.org/PR105169>`__) (The paper is partially implemented. ``zip_transform_view`` is implemented in this release) +- P2988R12: ``std::optional<T&>`` (`Github <https://llvm.org/PR148131>`__) - P3044R2: sub-``string_view`` from ``string`` (`Github <https://llvm.org/PR148140>`__) - P3223R2: Making ``std::istream::ignore`` less surprising (`Github <https://llvm.org/PR148178>`__) - P3060R3: Add ``std::views::indices(n)`` (`Github <https://llvm.org/PR148175>`__) @@ -66,8 +67,8 @@ Improvements and New Features by up to 2.5x - The performance of ``erase(iterator, iterator)`` in the unordered containers has been improved by up to 1.9x - The performance of ``map::insert_or_assign`` has been improved by up to 2x -- ``ofstream::write`` and ``ifstream::read`` have been optimized to pass through large reads and writes to system calls - directly instead of copying them in chunks. +- ``ofstream::write`` has been optimized to pass through large strings to system calls directly instead of copying them + in chunks into a buffer. - Multiple internal types have been refactored to use ``[[no_unique_address]]``, resulting in faster compile times and reduced debug information. @@ -81,6 +82,10 @@ Improvements and New Features - The ``std::{generate, generate_n}`` and ``std::ranges::generate_n`` algorithms have been optimized for segmented iterators, resulting in a performance improvement for ``std::deque<short>`` and ``std::join_view<vector<vector<short>>>`` iterators. +- ``std::atomic::wait`` has been refactored to accept more types to use platform native wait functions directly. + This is guarded behind the ABI Macro ``_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE``. + +- The ``num_get::do_get`` integral overloads have been optimized, resulting in a performance improvement of up to 2.8x. Deprecations and Removals ------------------------- @@ -113,5 +118,8 @@ ABI Affecting Changes potentially inheriting from the types they wrap. At this point in time we are not aware of any ABI changes caused by this. +- ``ranges::iota_view`` is now aware of ``__int128``. This causes ``iota_view::difference_type`` to change from + ``long long`` to ``__int128`` in some cases. + Build System Changes -------------------- diff --git a/libcxx/docs/Status/Cxx23Issues.csv b/libcxx/docs/Status/Cxx23Issues.csv index 5a68b51..389e1ad 100644 --- a/libcxx/docs/Status/Cxx23Issues.csv +++ b/libcxx/docs/Status/Cxx23Issues.csv @@ -58,7 +58,7 @@ "`LWG3495 <https://wg21.link/LWG3495>`__","``constexpr launder`` makes pointers to inactive members of unions usable","2021-02 (Virtual)","|Nothing To Do|","","`#104316 <https://github.com/llvm/llvm-project/issues/104316>`__","" "`LWG3500 <https://wg21.link/LWG3500>`__","``join_view::iterator::operator->()`` is bogus","2021-02 (Virtual)","|Complete|","14","`#104318 <https://github.com/llvm/llvm-project/issues/104318>`__","" "`LWG3502 <https://wg21.link/LWG3502>`__","``elements_view`` should not be allowed to return dangling reference","2021-02 (Virtual)","|Complete|","16","`#104319 <https://github.com/llvm/llvm-project/issues/104319>`__","" -"`LWG3505 <https://wg21.link/LWG3505>`__","``split_view::outer-iterator::operator++`` misspecified","2021-02 (Virtual)","","","`#104320 <https://github.com/llvm/llvm-project/issues/104320>`__","" +"`LWG3505 <https://wg21.link/LWG3505>`__","``split_view::outer-iterator::operator++`` misspecified","2021-02 (Virtual)","|Complete|","15","`#104320 <https://github.com/llvm/llvm-project/issues/104320>`__","" "","","","","","","" "`LWG2774 <https://wg21.link/LWG2774>`__","``std::function`` construction vs assignment","2021-06 (Virtual)","","","`#104321 <https://github.com/llvm/llvm-project/issues/104321>`__","" "`LWG2818 <https://wg21.link/LWG2818>`__","``::std::`` everywhere rule needs tweaking","2021-06 (Virtual)","|Nothing To Do|","","`#104322 <https://github.com/llvm/llvm-project/issues/104322>`__","" diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv index e0e47b8..0455643 100644 --- a/libcxx/docs/Status/Cxx2cPapers.csv +++ b/libcxx/docs/Status/Cxx2cPapers.csv @@ -81,7 +81,7 @@ "`P3379R0 <https://wg21.link/P3379R0>`__","Constrain ``std::expected`` equality operators","2024-11 (Wrocław)","|Complete|","21","`#118135 <https://github.com/llvm/llvm-project/issues/118135>`__","" "`P2862R1 <https://wg21.link/P2862R1>`__","``text_encoding::name()`` should never return null values","2024-11 (Wrocław)","","","`#118371 <https://github.com/llvm/llvm-project/issues/118371>`__","" "`P2897R7 <https://wg21.link/P2897R7>`__","``aligned_accessor``: An ``mdspan`` accessor expressing pointer over-alignment","2024-11 (Wrocław)","|Complete|","21","`#118372 <https://github.com/llvm/llvm-project/issues/118372>`__","" -"`P3355R1 <https://wg21.link/P3355R1>`__","Fix ``submdspan`` for C++26","2024-11 (Wrocław)","","","`#118373 <https://github.com/llvm/llvm-project/issues/118373>`__","" +"`P3355R2 <https://wg21.link/P3355R2>`__","Fix ``submdspan`` for C++26","2024-11 (Wrocław)","","","`#118373 <https://github.com/llvm/llvm-project/issues/118373>`__","" "`P3222R0 <https://wg21.link/P3222R0>`__","Fix C++26 by adding transposed special cases for P2642 layouts","2024-11 (Wrocław)","","","`#118374 <https://github.com/llvm/llvm-project/issues/118374>`__","" "`P3050R2 <https://wg21.link/P3050R2>`__","Fix C++26 by optimizing ``linalg::conjugated`` for noncomplex value types","2024-11 (Wrocław)","","","`#118375 <https://github.com/llvm/llvm-project/issues/118375>`__","" "`P3396R1 <https://wg21.link/P3396R1>`__","``std::execution`` wording fixes","2024-11 (Wrocław)","","","`#118376 <https://github.com/llvm/llvm-project/issues/118376>`__","" @@ -122,7 +122,7 @@ "`P3293R3 <https://wg21.link/P3293R3>`__","Splicing a base class subobject","2025-06 (Sofia)","","","`#148125 <https://github.com/llvm/llvm-project/issues/148125>`__","" "`P3491R3 <https://wg21.link/P3491R3>`__","``define_static_{string,object,array}``","2025-06 (Sofia)","","","`#148126 <https://github.com/llvm/llvm-project/issues/148126>`__","" "`P3096R12 <https://wg21.link/P3096R12>`__","Function Parameter Reflection in Reflection for C++26","2025-06 (Sofia)","","","`#148127 <https://github.com/llvm/llvm-project/issues/148127>`__","" -"`P2988R12 <https://wg21.link/P2988R12>`__","``std::optional<T&>``","2025-06 (Sofia)","","","`#148131 <https://github.com/llvm/llvm-project/issues/148131>`__","" +"`P2988R12 <https://wg21.link/P2988R12>`__","``std::optional<T&>``","2025-06 (Sofia)","|Complete|","22","`#148131 <https://github.com/llvm/llvm-project/issues/148131>`__","" "`P3348R4 <https://wg21.link/P3348R4>`__","C++26 should refer to C23 not C17","2025-06 (Sofia)","","","`#148133 <https://github.com/llvm/llvm-project/issues/148133>`__","" "`P3037R6 <https://wg21.link/P3037R6>`__","``constexpr`` ``std::shared_ptr`` and friends","2025-06 (Sofia)","","","`#148135 <https://github.com/llvm/llvm-project/issues/148135>`__","" "`P3284R4 <https://wg21.link/P3284R4>`__","``write_env`` and ``unstoppable`` Sender Adaptors","2025-06 (Sofia)","","","`#148136 <https://github.com/llvm/llvm-project/issues/148136>`__","" diff --git a/libcxx/docs/VendorDocumentation.rst b/libcxx/docs/VendorDocumentation.rst index 7eba598..05dc341 100644 --- a/libcxx/docs/VendorDocumentation.rst +++ b/libcxx/docs/VendorDocumentation.rst @@ -81,12 +81,14 @@ CMake invocation at ``<monorepo>/llvm``: .. code-block:: bash $ mkdir build - $ cmake -G Ninja -S llvm -B build -DLLVM_ENABLE_PROJECTS="clang" \ # Configure - -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \ - -DLLVM_RUNTIME_TARGETS="<target-triple>" - $ ninja -C build runtimes # Build - $ ninja -C build check-runtimes # Test - $ ninja -C build install-runtimes # Install + $ cmake -G Ninja -S llvm -B build \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DLLVM_ENABLE_PROJECTS="clang" \ # Configure + -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind;compiler-rt" \ + -DLLVM_RUNTIME_TARGETS="<target-triple>" + $ ninja -C build runtimes # Build + $ ninja -C build check-runtimes # Test + $ ninja -C build install-runtimes # Install .. note:: - This type of build is also commonly called a "Runtimes build", but we would like to move @@ -162,10 +164,10 @@ General purpose options .. option:: LIBCXX_ENABLE_FILESYSTEM:BOOL - **Default**: ``ON`` except on Windows when using MSVC. + **Default**: ``ON`` This option can be used to enable or disable the filesystem components on - platforms that may not support them. For example on Windows when using MSVC. + platforms that may not support them. .. option:: LIBCXX_ENABLE_WIDE_CHARACTERS:BOOL @@ -376,6 +378,12 @@ newer (19.14) is required. Libc++ also supports being built with clang targeting MinGW environments. +Libc++ supports Windows 7 or newer. However, the minimum runtime version +of the build is determined by the ``_WIN32_WINNT`` define, which in many +SDKs defaults to the latest version. To build a version that runs on an +older version, define e.g. ``_WIN32_WINNT=0x601`` while building libc++, +to target Windows 7. + CMake + Visual Studio --------------------- @@ -587,3 +595,45 @@ libc++'s ABI guarantees ======================= Libc++ provides several ABI guarantees, which are documented :ref:`here <ABIGuarantees>`. + +Availability Markup +=================== + +Libc++ is shipped by various vendors. In particular, it is used as a system library on macOS, iOS and other Apple +platforms. In order for users to be able to compile a binary that is intended to be deployed to an older version of a +platform, Clang provides `availability attributes <https://clang.llvm.org/docs/AttributeReference.html#availability>`_. +These attributes can be placed on declarations and are used to describe the life cycle of a symbol in the library. + +The main goal is to ensure a compile-time error if a symbol that hasn't been introduced in a previously released library +is used in a program that targets that previously released library. Normally, this would be a load-time error when one +tries to launch the program against the older library. + +For example, the filesystem library was introduced in the dylib in LLVM 9. On Apple platforms, this corresponds to +macOS 10.15. If a user compiles on a macOS 10.15 host but targets macOS 10.13 with their program, the compiler would +normally not complain (because the required declarations are in the headers), but the dynamic loader would fail to find +the symbols when actually trying to launch the program on macOS 10.13. To turn this into a compile-time issue instead, +declarations are annotated with when they were introduced, and the compiler can produce a diagnostic if the program +references something that isn't available on the deployment target. + +This mechanism is general in nature, and any vendor can add their markup to the library (see below). Whenever a new +feature is added that requires support in the shared library, two macros are added below to allow marking the feature as +unavailable: + +1. A macro named ``_LIBCPP_AVAILABILITY_HAS_<feature>`` which must be defined to ``_LIBCPP_INTRODUCED_IN_<version>`` for + the appropriate LLVM version. + +2. A macro named ``_LIBCPP_AVAILABILITY_<feature>``, which must be defined to ``_LIBCPP_INTRODUCED_IN_<version>_MARKUP`` + for the appropriate LLVM version. + +When vendors decide to ship the feature as part of their shared library, they can update the +``_LIBCPP_INTRODUCED_IN_<version>`` macro (and the markup counterpart) based on the platform version they shipped that +version of LLVM in. The library will then use this markup to provide an optimal user experience on these platforms. + +Furthermore, many features in the standard library have corresponding feature-test macros. The +``_LIBCPP_AVAILABILITY_HAS_<feature>`` macros are checked by the corresponding feature-test macros generated by +``generate_feature_test_macro_components.py`` to ensure that the library doesn't announce a feature as being implemented +if it is unavailable on the deployment target. + +Note that this mechanism is disabled by default in the "upstream" libc++. Availability annotations are only meaningful +when shipping libc++ inside a platform (i.e. as a system library), and so vendors that want them should turn those +annotations on at CMake configuration time. diff --git a/libcxx/docs/index.rst b/libcxx/docs/index.rst index 03dfb9d..d006b52 100644 --- a/libcxx/docs/index.rst +++ b/libcxx/docs/index.rst @@ -147,7 +147,7 @@ macOS 10.13+ i386, x86_64, arm64 FreeBSD 12+ i386, x86_64, arm Linux i386, x86_64, arm, arm64 Only glibc-2.24 and later and no other libc is officially supported Android 5.0+ i386, x86_64, arm, arm64 -Windows i386, x86_64, arm64 Both MSVC and MinGW style environments, ABI in MSVC environments is :doc:`unstable <DesignDocs/ABIVersioning>` +Windows 7+ i386, x86_64, arm64 Both MSVC and MinGW style environments, ABI in MSVC environments is :doc:`unstable <DesignDocs/ABIVersioning>` AIX 7.2TL5+ powerpc, powerpc64 Embedded (picolibc) arm ===================== ========================= ============================ diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 09d4552..cbcd764 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -194,6 +194,7 @@ set(files __algorithm/simd_utils.h __algorithm/sort.h __algorithm/sort_heap.h + __algorithm/specialized_algorithms.h __algorithm/stable_partition.h __algorithm/stable_sort.h __algorithm/swap_ranges.h @@ -328,6 +329,8 @@ set(files __configuration/abi.h __configuration/availability.h __configuration/compiler.h + __configuration/experimental.h + __configuration/hardening.h __configuration/language.h __configuration/platform.h __coroutine/coroutine_handle.h @@ -518,7 +521,6 @@ set(files __locale_dir/locale_base_api.h __locale_dir/locale_base_api/bsd_locale_fallbacks.h __locale_dir/locale_base_api/ibm.h - __locale_dir/locale_base_api/musl.h __locale_dir/locale_base_api/openbsd.h __locale_dir/messages.h __locale_dir/money.h @@ -531,6 +533,7 @@ set(files __locale_dir/support/fuchsia.h __locale_dir/support/linux.h __locale_dir/support/netbsd.h + __locale_dir/support/newlib.h __locale_dir/support/no_locale/characters.h __locale_dir/support/no_locale/strtonum.h __locale_dir/support/windows.h @@ -568,7 +571,6 @@ set(files __mdspan/mdspan.h __memory/addressof.h __memory/align.h - __memory/aligned_alloc.h __memory/allocate_at_least.h __memory/allocation_guard.h __memory/allocator.h @@ -820,7 +822,6 @@ set(files __type_traits/is_array.h __type_traits/is_assignable.h __type_traits/is_base_of.h - __type_traits/is_bounded_array.h __type_traits/is_callable.h __type_traits/is_char_like_type.h __type_traits/is_class.h @@ -857,7 +858,6 @@ set(files __type_traits/is_reference.h __type_traits/is_reference_wrapper.h __type_traits/is_referenceable.h - __type_traits/is_replaceable.h __type_traits/is_same.h __type_traits/is_scalar.h __type_traits/is_signed.h @@ -871,7 +871,6 @@ set(files __type_traits/is_trivially_destructible.h __type_traits/is_trivially_lexicographically_comparable.h __type_traits/is_trivially_relocatable.h - __type_traits/is_unbounded_array.h __type_traits/is_union.h __type_traits/is_unqualified.h __type_traits/is_unsigned.h @@ -1065,7 +1064,6 @@ set(files sstream stack stdatomic.h - stdbool.h stddef.h stdexcept stdio.h diff --git a/libcxx/include/__algorithm/all_of.h b/libcxx/include/__algorithm/all_of.h index 6acc117..9bdb20a 100644 --- a/libcxx/include/__algorithm/all_of.h +++ b/libcxx/include/__algorithm/all_of.h @@ -10,24 +10,28 @@ #ifndef _LIBCPP___ALGORITHM_ALL_OF_H #define _LIBCPP___ALGORITHM_ALL_OF_H +#include <__algorithm/any_of.h> #include <__config> #include <__functional/identity.h> #include <__type_traits/invoke.h> +#include <__utility/forward.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template <class _Iter, class _Sent, class _Proj, class _Pred> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool __all_of(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { - for (; __first != __last; ++__first) { - if (!std::__invoke(__pred, std::__invoke(__proj, *__first))) - return false; - } - return true; + using _Ref = decltype(std::__invoke(__proj, *__first)); + auto __negated_pred = [&__pred](_Ref __arg) -> bool { return !std::__invoke(__pred, std::forward<_Ref>(__arg)); }; + return !std::__any_of(std::move(__first), std::move(__last), __negated_pred, __proj); } template <class _InputIterator, class _Predicate> @@ -39,4 +43,6 @@ all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_ALL_OF_H diff --git a/libcxx/include/__algorithm/copy_n.h b/libcxx/include/__algorithm/copy_n.h index f93f392..56fb448 100644 --- a/libcxx/include/__algorithm/copy_n.h +++ b/libcxx/include/__algorithm/copy_n.h @@ -10,31 +10,63 @@ #define _LIBCPP___ALGORITHM_COPY_N_H #include <__algorithm/copy.h> +#include <__algorithm/iterator_operations.h> #include <__config> #include <__iterator/iterator_traits.h> #include <__type_traits/enable_if.h> #include <__utility/convert_to_integral.h> +#include <__utility/move.h> +#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD +template <class _AlgPolicy, + class _InIter, + class _OutIter, + __enable_if_t<__has_random_access_iterator_category<_InIter>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter> +__copy_n(_InIter __first, typename _IterOps<_AlgPolicy>::template __difference_type<_InIter> __n, _OutIter __result) { + return std::__copy(__first, __first + __n, std::move(__result)); +} + +template <class _AlgPolicy, + class _InIter, + class _OutIter, + __enable_if_t<!__has_random_access_iterator_category<_InIter>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter> +__copy_n(_InIter __first, typename _IterOps<_AlgPolicy>::template __difference_type<_InIter> __n, _OutIter __result) { + while (__n != 0) { + *__result = *__first; + ++__first; + ++__result; + --__n; + } + return std::make_pair(std::move(__first), std::move(__result)); +} + +// The InputIterator case is handled specially here because it's been written in a way to avoid incrementing __first +// if not absolutely required. This was done to allow its use with istream_iterator and we want to avoid breaking +// people, at least currently. +// See https://github.com/llvm/llvm-project/commit/99847d2bf132854fffa019bab19818768102ccad template <class _InputIterator, class _Size, class _OutputIterator, - __enable_if_t<__has_input_iterator_category<_InputIterator>::value && - !__has_random_access_iterator_category<_InputIterator>::value, - int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator -copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) { - typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; - _IntegralSize __n = __orig_n; - if (__n > 0) { + __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +copy_n(_InputIterator __first, _Size __n, _OutputIterator __result) { + using _IntegralSize = decltype(std::__convert_to_integral(__n)); + _IntegralSize __converted = __n; + if (__converted > 0) { *__result = *__first; ++__result; - for (--__n; __n > 0; --__n) { + for (--__converted; __converted > 0; --__converted) { ++__first; *__result = *__first; ++__result; @@ -46,15 +78,17 @@ copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) { template <class _InputIterator, class _Size, class _OutputIterator, - __enable_if_t<__has_random_access_iterator_category<_InputIterator>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator -copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) { - typedef typename iterator_traits<_InputIterator>::difference_type difference_type; - typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; - _IntegralSize __n = __orig_n; - return std::copy(__first, __first + difference_type(__n), __result); + __enable_if_t<!__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +copy_n(_InputIterator __first, _Size __n, _OutputIterator __result) { + using _IntegralSize = decltype(std::__convert_to_integral(__n)); + _IntegralSize __converted = __n; + return std::__copy_n<_ClassicAlgPolicy>(__first, __iterator_difference_type<_InputIterator>(__converted), __result) + .second; } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_COPY_N_H diff --git a/libcxx/include/__algorithm/fill_n.h b/libcxx/include/__algorithm/fill_n.h index 426fe22..3d06ea4 100644 --- a/libcxx/include/__algorithm/fill_n.h +++ b/libcxx/include/__algorithm/fill_n.h @@ -10,13 +10,13 @@ #define _LIBCPP___ALGORITHM_FILL_N_H #include <__algorithm/for_each_n_segment.h> -#include <__algorithm/min.h> +#include <__algorithm/specialized_algorithms.h> #include <__config> -#include <__fwd/bit_reference.h> #include <__iterator/iterator_traits.h> #include <__iterator/segmented_iterator.h> -#include <__memory/pointer_traits.h> +#include <__type_traits/enable_if.h> #include <__utility/convert_to_integral.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -29,7 +29,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD // fill_n isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset. -template <class _OutputIterator, class _Size, class _Tp> +template < + class _OutputIterator, + class _Size, + class _Tp, + __enable_if_t<!__specialized_algorithm<_Algorithm::__fill_n, __single_iterator<_OutputIterator> >::__has_algorithm, + int> = 0> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) { #ifndef _LIBCPP_CXX03_LANG @@ -47,42 +52,14 @@ __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) { return __first; } -template <bool _FillVal, class _Cp> -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void -__fill_n_bool(__bit_iterator<_Cp, false> __first, typename __size_difference_type_traits<_Cp>::size_type __n) { - using _It = __bit_iterator<_Cp, false>; - using __storage_type = typename _It::__storage_type; - - const int __bits_per_word = _It::__bits_per_word; - // do first partial word - if (__first.__ctz_ != 0) { - __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); - __storage_type __dn = std::min(__clz_f, __n); - std::__fill_masked_range(std::__to_address(__first.__seg_), __clz_f - __dn, __first.__ctz_, _FillVal); - __n -= __dn; - ++__first.__seg_; - } - // do middle whole words - __storage_type __nw = __n / __bits_per_word; - std::__fill_n(std::__to_address(__first.__seg_), __nw, _FillVal ? static_cast<__storage_type>(-1) : 0); - __n -= __nw * __bits_per_word; - // do last partial word - if (__n > 0) { - __first.__seg_ += __nw; - std::__fill_masked_range(std::__to_address(__first.__seg_), __bits_per_word - __n, 0u, _FillVal); - } -} - -template <class _Cp, class _Size> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> -__fill_n(__bit_iterator<_Cp, false> __first, _Size __n, const bool& __value) { - if (__n > 0) { - if (__value) - std::__fill_n_bool<true>(__first, __n); - else - std::__fill_n_bool<false>(__first, __n); - } - return __first + __n; +template <class _OutIter, + class _Size, + class _Tp, + __enable_if_t<__specialized_algorithm<_Algorithm::__fill_n, __single_iterator<_OutIter> >::__has_algorithm, + int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutIter __fill_n(_OutIter __first, _Size __n, const _Tp& __value) { + return __specialized_algorithm<_Algorithm::__fill_n, __single_iterator<_OutIter> >()( + std::move(__first), __n, __value); } template <class _OutputIterator, class _Size, class _Tp> diff --git a/libcxx/include/__algorithm/find.h b/libcxx/include/__algorithm/find.h index 10379d7..d03421b 100644 --- a/libcxx/include/__algorithm/find.h +++ b/libcxx/include/__algorithm/find.h @@ -230,7 +230,8 @@ struct __find_segment { template <class _InputIterator, class _Proj> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _InputIterator operator()(_InputIterator __first, _InputIterator __last, _Proj& __proj) const { - return std::__find(__first, __last, __value_, __proj); + return std::__rewrap_iter( + __first, std::__find(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __value_, __proj)); } }; diff --git a/libcxx/include/__algorithm/iterator_operations.h b/libcxx/include/__algorithm/iterator_operations.h index e5c89c1..1aa2f8d16 100644 --- a/libcxx/include/__algorithm/iterator_operations.h +++ b/libcxx/include/__algorithm/iterator_operations.h @@ -219,6 +219,9 @@ private: template <class _AlgPolicy, class _Iter> using __policy_iter_diff_t _LIBCPP_NODEBUG = typename _IterOps<_AlgPolicy>::template __difference_type<_Iter>; +template <class _AlgPolicy, class _Iter> +using __policy_value_type _LIBCPP_NODEBUG = typename _IterOps<_AlgPolicy>::template __value_type<_Iter>; + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS diff --git a/libcxx/include/__algorithm/none_of.h b/libcxx/include/__algorithm/none_of.h index e6bd197..1e1c8d1a 100644 --- a/libcxx/include/__algorithm/none_of.h +++ b/libcxx/include/__algorithm/none_of.h @@ -10,7 +10,9 @@ #ifndef _LIBCPP___ALGORITHM_NONE_OF_H #define _LIBCPP___ALGORITHM_NONE_OF_H +#include <__algorithm/any_of.h> #include <__config> +#include <__functional/identity.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -21,10 +23,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _InputIterator, class _Predicate> [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { - for (; __first != __last; ++__first) - if (__pred(*__first)) - return false; - return true; + __identity __proj; + return !std::__any_of(__first, __last, __pred, __proj); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/ranges_copy_n.h b/libcxx/include/__algorithm/ranges_copy_n.h index 1fbc616..6bee4c3 100644 --- a/libcxx/include/__algorithm/ranges_copy_n.h +++ b/libcxx/include/__algorithm/ranges_copy_n.h @@ -9,16 +9,12 @@ #ifndef _LIBCPP___ALGORITHM_RANGES_COPY_N_H #define _LIBCPP___ALGORITHM_RANGES_COPY_N_H -#include <__algorithm/copy.h> +#include <__algorithm/copy_n.h> #include <__algorithm/in_out_result.h> #include <__algorithm/iterator_operations.h> -#include <__algorithm/ranges_copy.h> #include <__config> -#include <__functional/identity.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> -#include <__iterator/unreachable_sentinel.h> -#include <__iterator/wrap_iter.h> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -37,32 +33,13 @@ namespace ranges { template <class _Ip, class _Op> using copy_n_result = in_out_result<_Ip, _Op>; -// TODO: Merge this with copy_n struct __copy_n { - template <class _InIter, class _DiffType, class _OutIter> - _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter> - __go(_InIter __first, _DiffType __n, _OutIter __result) { - while (__n != 0) { - *__result = *__first; - ++__first; - ++__result; - --__n; - } - return {std::move(__first), std::move(__result)}; - } - - template <random_access_iterator _InIter, class _DiffType, random_access_iterator _OutIter> - _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter> - __go(_InIter __first, _DiffType __n, _OutIter __result) { - auto __ret = std::__copy(__first, __first + __n, __result); - return {__ret.first, __ret.second}; - } - template <input_iterator _Ip, weakly_incrementable _Op> requires indirectly_copyable<_Ip, _Op> _LIBCPP_HIDE_FROM_ABI constexpr copy_n_result<_Ip, _Op> operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const { - return __go(std::move(__first), __n, std::move(__result)); + auto __res = std::__copy_n<_RangeAlgPolicy>(std::move(__first), __n, std::move(__result)); + return {std::move(__res.first), std::move(__res.second)}; } }; diff --git a/libcxx/include/__algorithm/simd_utils.h b/libcxx/include/__algorithm/simd_utils.h index aaeb8a8..f73c9ea 100644 --- a/libcxx/include/__algorithm/simd_utils.h +++ b/libcxx/include/__algorithm/simd_utils.h @@ -114,6 +114,27 @@ template <class _VecT, class _Iter> }(make_index_sequence<__simd_vector_size_v<_VecT>>{}); } +// Load the first _Np elements, zero the rest +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wpsabi") +template <class _VecT, size_t _Np, class _Iter> +[[__nodiscard__]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _VecT __partial_load(_Iter __iter) noexcept { + return [=]<size_t... _LoadIndices, size_t... _ZeroIndices>( + index_sequence<_LoadIndices...>, index_sequence<_ZeroIndices...>) _LIBCPP_ALWAYS_INLINE noexcept { + return _VecT{__iter[_LoadIndices]..., ((void)_ZeroIndices, 0)...}; + }(make_index_sequence<_Np>{}, make_index_sequence<__simd_vector_size_v<_VecT> - _Np>{}); +} + +// Create a vector where every elements is __val +template <class _VecT> +[[__nodiscard__]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _VecT +__broadcast(__simd_vector_underlying_type_t<_VecT> __val) { + return [&]<std::size_t... _Indices>(index_sequence<_Indices...>) { + return _VecT{((void)_Indices, __val)...}; + }(make_index_sequence<__simd_vector_size_v<_VecT>>()); +} +_LIBCPP_DIAGNOSTIC_POP + template <class _Tp, size_t _Np> [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __any_of(__simd_vector<_Tp, _Np> __vec) noexcept { return __builtin_reduce_or(__builtin_convertvector(__vec, __simd_vector<bool, _Np>)); @@ -125,6 +146,11 @@ template <class _Tp, size_t _Np> } template <class _Tp, size_t _Np> +[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __none_of(__simd_vector<_Tp, _Np> __vec) noexcept { + return !__builtin_reduce_or(__builtin_convertvector(__vec, __simd_vector<bool, _Np>)); +} + +template <class _Tp, size_t _Np> [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t __find_first_set(__simd_vector<_Tp, _Np> __vec) noexcept { using __mask_vec = __simd_vector<bool, _Np>; diff --git a/libcxx/include/__algorithm/specialized_algorithms.h b/libcxx/include/__algorithm/specialized_algorithms.h new file mode 100644 index 0000000..a2ffd36 --- /dev/null +++ b/libcxx/include/__algorithm/specialized_algorithms.h @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_SPECIALIZED_ALGORITHMS_H +#define _LIBCPP___ALGORITHM_SPECIALIZED_ALGORITHMS_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace _Algorithm { +struct __fill_n {}; +} // namespace _Algorithm + +template <class> +struct __single_iterator; + +// This struct allows specializing algorithms for specific arguments. This is useful when we know a more efficient +// algorithm implementation for e.g. library-defined iterators. _Alg is one of tags defined inside the _Algorithm +// namespace above. _Ranges is an essentially arbitrary subset of the arguments to the algorithm that are used for +// dispatching. This set is specific to the algorithm: look at each algorithm to see which arguments they use for +// dispatching to specialized algorithms. +// +// A specialization of `__specialized_algorithm` has to define `__has_algorithm` to true for the specialized algorithm +// to be used. This is intended for cases where iterators can do generic unwrapping and forward to a different +// specialization of `__specialized_algorithm`. +// +// If __has_algorithm is true, there has to be an operator() which will get called with the actual arguments to the +// algorithm. +template <class _Alg, class... _Ranges> +struct __specialized_algorithm { + static const bool __has_algorithm = false; +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SPECIALIZED_ALGORITHMS_H diff --git a/libcxx/include/__atomic/atomic.h b/libcxx/include/__atomic/atomic.h index 4483582..554c111 100644 --- a/libcxx/include/__atomic/atomic.h +++ b/libcxx/include/__atomic/atomic.h @@ -206,6 +206,8 @@ struct __atomic_base<_Tp, true> : public __atomic_base<_Tp, false> { // __atomic_base<int, false>. So specializing __atomic_base<_Tp> does not work template <class _Tp, bool _IsIntegral> struct __atomic_waitable_traits<__atomic_base<_Tp, _IsIntegral> > { + using __value_type _LIBCPP_NODEBUG = _Tp; + static _LIBCPP_HIDE_FROM_ABI _Tp __atomic_load(const __atomic_base<_Tp, _IsIntegral>& __a, memory_order __order) { return __a.load(__order); } diff --git a/libcxx/include/__atomic/atomic_flag.h b/libcxx/include/__atomic/atomic_flag.h index 28ed2d5..321a628 100644 --- a/libcxx/include/__atomic/atomic_flag.h +++ b/libcxx/include/__atomic/atomic_flag.h @@ -76,6 +76,8 @@ struct atomic_flag { template <> struct __atomic_waitable_traits<atomic_flag> { + using __value_type _LIBCPP_NODEBUG = _LIBCPP_ATOMIC_FLAG_TYPE; + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE __atomic_load(const atomic_flag& __a, memory_order __order) { return std::__cxx_atomic_load(&__a.__a_, __order); } diff --git a/libcxx/include/__atomic/atomic_ref.h b/libcxx/include/__atomic/atomic_ref.h index ec5ae2c..9a36aaa 100644 --- a/libcxx/include/__atomic/atomic_ref.h +++ b/libcxx/include/__atomic/atomic_ref.h @@ -233,6 +233,8 @@ protected: template <class _Tp> struct __atomic_waitable_traits<__atomic_ref_base<_Tp>> { + using __value_type _LIBCPP_NODEBUG = _Tp; + static _LIBCPP_HIDE_FROM_ABI _Tp __atomic_load(const __atomic_ref_base<_Tp>& __a, memory_order __order) { return __a.load(__order); } diff --git a/libcxx/include/__atomic/atomic_sync.h b/libcxx/include/__atomic/atomic_sync.h index 93953df..d0119ab 100644 --- a/libcxx/include/__atomic/atomic_sync.h +++ b/libcxx/include/__atomic/atomic_sync.h @@ -18,7 +18,10 @@ #include <__thread/poll_with_backoff.h> #include <__type_traits/conjunction.h> #include <__type_traits/decay.h> +#include <__type_traits/has_unique_object_representation.h> #include <__type_traits/invoke.h> +#include <__type_traits/is_same.h> +#include <__type_traits/is_trivially_copyable.h> #include <__type_traits/void_t.h> #include <__utility/declval.h> #include <cstring> @@ -38,6 +41,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD // The below implementations look ugly to support C++03 template <class _Tp, class = void> struct __atomic_waitable_traits { + using __value_type _LIBCPP_NODEBUG = void; + template <class _AtomicWaitable> static void __atomic_load(_AtomicWaitable&&, memory_order) = delete; @@ -58,6 +63,9 @@ struct __atomic_waitable< _Tp, #if _LIBCPP_STD_VER >= 20 # if _LIBCPP_HAS_THREADS +# if !_LIBCPP_AVAILABILITY_HAS_NEW_SYNC + +// old dylib interface kept for backwards compatibility _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*) _NOEXCEPT; _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*) _NOEXCEPT; _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*) _NOEXCEPT; @@ -69,6 +77,114 @@ _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*) _NOEXCEPT; _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t) _NOEXCEPT; +# endif // !_LIBCPP_AVAILABILITY_HAS_NEW_SYNC + +// new dylib interface + +// return the global contention state's current value for the address +_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t +__atomic_monitor_global(void const* __address) _NOEXCEPT; + +// wait on the global contention state to be changed from the given value for the address +_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void +__atomic_wait_global_table(void const* __address, __cxx_contention_t __monitor_value) _NOEXCEPT; + +// notify one waiter waiting on the global contention state for the address +_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_global_table(void const*) _NOEXCEPT; + +// notify all waiters waiting on the global contention state for the address +_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_global_table(void const*) _NOEXCEPT; + +// wait on the address directly with the native platform wait +template <std::size_t _Size> +_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void +__atomic_wait_native(void const* __address, void const* __old_value) _NOEXCEPT; + +// notify one waiter waiting on the address directly with the native platform wait +template <std::size_t _Size> +_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_native(const void*) _NOEXCEPT; + +// notify all waiters waiting on the address directly with the native platform wait +template <std::size_t _Size> +_LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_native(const void*) _NOEXCEPT; + +# ifdef __linux__ +# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) _APPLY(4) +# elif defined(__APPLE__) +# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) \ + _APPLY(4) \ + _APPLY(8) +# elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8 +# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) _APPLY(8) +# elif defined(_WIN32) +# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) _APPLY(8) +# else +# define _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_APPLY) _APPLY(sizeof(__cxx_contention_t)) +# endif // __linux__ + +// concepts defines the types are supported natively by the platform's wait + +# if defined(_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE) + +_LIBCPP_HIDE_FROM_ABI constexpr bool __has_native_atomic_wait_impl(size_t __size) { + switch (__size) { +# define _LIBCPP_MAKE_CASE(n) \ + case n: \ + return true; + _LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_LIBCPP_MAKE_CASE) + default: + return false; +# undef _LIBCPP_MAKE_CASE + }; +} + +template <class _Tp> +concept __has_native_atomic_wait = + has_unique_object_representations_v<_Tp> && is_trivially_copyable_v<_Tp> && + __has_native_atomic_wait_impl(sizeof(_Tp)); + +# else // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE + +template <class _Tp> +concept __has_native_atomic_wait = is_same_v<_Tp, __cxx_contention_t>; + +# endif // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE + +# if _LIBCPP_AVAILABILITY_HAS_NEW_SYNC + +template <class _AtomicWaitable, class _Poll> +struct __atomic_wait_backoff_impl { + const _AtomicWaitable& __a_; + _Poll __poll_; + memory_order __order_; + + using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >; + using __value_type _LIBCPP_NODEBUG = typename __waitable_traits::__value_type; + + _LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const { + if (__elapsed > chrono::microseconds(4)) { + auto __contention_address = const_cast<const void*>( + static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a_))); + + if constexpr (__has_native_atomic_wait<__value_type>) { + auto __atomic_value = __waitable_traits::__atomic_load(__a_, __order_); + if (__poll_(__atomic_value)) + return true; + std::__atomic_wait_native<sizeof(__value_type)>(__contention_address, std::addressof(__atomic_value)); + } else { + __cxx_contention_t __monitor_val = std::__atomic_monitor_global(__contention_address); + auto __atomic_value = __waitable_traits::__atomic_load(__a_, __order_); + if (__poll_(__atomic_value)) + return true; + std::__atomic_wait_global_table(__contention_address, __monitor_val); + } + } else { + } // poll + return false; + } +}; + +# else // _LIBCPP_AVAILABILITY_HAS_NEW_SYNC template <class _AtomicWaitable, class _Poll> struct __atomic_wait_backoff_impl { @@ -112,6 +228,8 @@ struct __atomic_wait_backoff_impl { } }; +# endif // _LIBCPP_AVAILABILITY_HAS_NEW_SYNC + // The semantics of this function are similar to `atomic`'s // `.wait(T old, std::memory_order order)`, but instead of having a hardcoded // predicate (is the loaded value unequal to `old`?), the predicate function is @@ -133,6 +251,38 @@ _LIBCPP_HIDE_FROM_ABI void __atomic_wait_unless(const _AtomicWaitable& __a, memo /* backoff */ __backoff_fn); } +# if _LIBCPP_AVAILABILITY_HAS_NEW_SYNC + +template <class _AtomicWaitable> +_LIBCPP_HIDE_FROM_ABI void __atomic_notify_one(const _AtomicWaitable& __a) { + static_assert(__atomic_waitable<_AtomicWaitable>::value, ""); + using __value_type _LIBCPP_NODEBUG = typename __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__value_type; + using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >; + auto __contention_address = + const_cast<const void*>(static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a))); + if constexpr (__has_native_atomic_wait<__value_type>) { + std::__atomic_notify_one_native<sizeof(__value_type)>(__contention_address); + } else { + std::__atomic_notify_one_global_table(__contention_address); + } +} + +template <class _AtomicWaitable> +_LIBCPP_HIDE_FROM_ABI void __atomic_notify_all(const _AtomicWaitable& __a) { + static_assert(__atomic_waitable<_AtomicWaitable>::value, ""); + using __value_type _LIBCPP_NODEBUG = typename __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__value_type; + using __waitable_traits _LIBCPP_NODEBUG = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >; + auto __contention_address = + const_cast<const void*>(static_cast<const volatile void*>(__waitable_traits::__atomic_contention_address(__a))); + if constexpr (__has_native_atomic_wait<__value_type>) { + std::__atomic_notify_all_native<sizeof(__value_type)>(__contention_address); + } else { + std::__atomic_notify_all_global_table(__contention_address); + } +} + +# else // _LIBCPP_AVAILABILITY_HAS_NEW_SYNC + template <class _AtomicWaitable> _LIBCPP_HIDE_FROM_ABI void __atomic_notify_one(const _AtomicWaitable& __a) { static_assert(__atomic_waitable<_AtomicWaitable>::value, ""); @@ -145,6 +295,8 @@ _LIBCPP_HIDE_FROM_ABI void __atomic_notify_all(const _AtomicWaitable& __a) { std::__cxx_atomic_notify_all(__atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_contention_address(__a)); } +# endif + # else // _LIBCPP_HAS_THREADS template <class _AtomicWaitable, class _Poll> diff --git a/libcxx/include/__atomic/contention_t.h b/libcxx/include/__atomic/contention_t.h index 5b42a01..b7e3704 100644 --- a/libcxx/include/__atomic/contention_t.h +++ b/libcxx/include/__atomic/contention_t.h @@ -19,11 +19,35 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__)) +// The original definition of `__cxx_contention_t` seemed a bit arbitrary. +// When we enable the _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE ABI, +// use definitions that are based on what the underlying platform supports +// instead. +#if defined(_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE) + +# ifdef __linux__ +using __cxx_contention_t _LIBCPP_NODEBUG = int32_t; +# elif defined(__APPLE__) +using __cxx_contention_t _LIBCPP_NODEBUG = int64_t; +# elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8 +using __cxx_contention_t _LIBCPP_NODEBUG = int64_t; +# elif defined(_AIX) && !defined(__64BIT__) +using __cxx_contention_t _LIBCPP_NODEBUG = int32_t; +# elif defined(_WIN32) +using __cxx_contention_t _LIBCPP_NODEBUG = int64_t; +# else +using __cxx_contention_t _LIBCPP_NODEBUG = int64_t; +# endif // __linux__ + +#else // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE + +# if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__)) using __cxx_contention_t _LIBCPP_NODEBUG = int32_t; -#else +# else using __cxx_contention_t _LIBCPP_NODEBUG = int64_t; -#endif // __linux__ || (_AIX && !__64BIT__) +# endif // __linux__ || (_AIX && !__64BIT__) + +#endif // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE using __cxx_atomic_contention_t _LIBCPP_NODEBUG = __cxx_atomic_impl<__cxx_contention_t>; diff --git a/libcxx/include/__bit/has_single_bit.h b/libcxx/include/__bit/has_single_bit.h index d10ab7d..c49c518 100644 --- a/libcxx/include/__bit/has_single_bit.h +++ b/libcxx/include/__bit/has_single_bit.h @@ -25,7 +25,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <__unsigned_integer _Tp> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept { - return __t != 0 && ((__t & (__t - 1)) == 0); + return __builtin_popcountg(__t) == 1; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__bit_reference b/libcxx/include/__bit_reference index a3e6def..00bbc41 100644 --- a/libcxx/include/__bit_reference +++ b/libcxx/include/__bit_reference @@ -15,8 +15,10 @@ #include <__algorithm/copy_backward.h> #include <__algorithm/copy_n.h> #include <__algorithm/equal.h> +#include <__algorithm/fill_n.h> #include <__algorithm/min.h> #include <__algorithm/rotate.h> +#include <__algorithm/specialized_algorithms.h> #include <__algorithm/swap_ranges.h> #include <__assert> #include <__bit/countr.h> @@ -137,7 +139,7 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator bool() const _NOEXCEPT { return static_cast<bool>(*__seg_ & __mask_); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator~() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator~() const _NOEXCEPT { return !static_cast<bool>(*this); } @@ -467,10 +469,6 @@ private: template <class _Dp> friend struct __bit_array; - template <bool _FillVal, class _Dp> - _LIBCPP_CONSTEXPR_SINCE_CXX20 friend void - __fill_n_bool(__bit_iterator<_Dp, false> __first, typename __size_difference_type_traits<_Dp>::size_type __n); - template <class _Dp, bool _IC> _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_aligned( __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); @@ -537,6 +535,52 @@ private: template <bool _ToCount, class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __count_bool(__bit_iterator<_Dp, _IC>, typename __size_difference_type_traits<_Dp>::size_type); + + template <class, class...> + friend struct __specialized_algorithm; +}; + +template <class _Cp> +struct __specialized_algorithm<_Algorithm::__fill_n, __single_iterator<__bit_iterator<_Cp, false> > > { + static const bool __has_algorithm = true; + + template <bool _FillVal> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static void + __impl(__bit_iterator<_Cp, false> __first, typename __size_difference_type_traits<_Cp>::size_type __n) { + using _It = __bit_iterator<_Cp, false>; + using __storage_type = typename _It::__storage_type; + + const int __bits_per_word = _It::__bits_per_word; + // do first partial word + if (__first.__ctz_ != 0) { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = std::min(__clz_f, __n); + std::__fill_masked_range(std::__to_address(__first.__seg_), __clz_f - __dn, __first.__ctz_, _FillVal); + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + __storage_type __nw = __n / __bits_per_word; + std::__fill_n(std::__to_address(__first.__seg_), __nw, _FillVal ? static_cast<__storage_type>(-1) : 0); + __n -= __nw * __bits_per_word; + // do last partial word + if (__n > 0) { + __first.__seg_ += __nw; + std::__fill_masked_range(std::__to_address(__first.__seg_), __bits_per_word - __n, 0u, _FillVal); + } + } + + template <class _Size, class _Tp> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static __bit_iterator<_Cp, false> + operator()(__bit_iterator<_Cp, false> __first, _Size __n, const _Tp& __value) { + if (__n > 0) { + if (__value) + __impl<true>(__first, __n); + else + __impl<false>(__first, __n); + } + return __first + __n; + } }; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__charconv/from_chars_integral.h b/libcxx/include/__charconv/from_chars_integral.h index c1f033b..903e892 100644 --- a/libcxx/include/__charconv/from_chars_integral.h +++ b/libcxx/include/__charconv/from_chars_integral.h @@ -18,8 +18,8 @@ #include <__memory/addressof.h> #include <__system_error/errc.h> #include <__type_traits/enable_if.h> -#include <__type_traits/integral_constant.h> #include <__type_traits/is_integral.h> +#include <__type_traits/is_signed.h> #include <__type_traits/is_unsigned.h> #include <__type_traits/make_unsigned.h> #include <limits> diff --git a/libcxx/include/__charconv/to_chars_integral.h b/libcxx/include/__charconv/to_chars_integral.h index f10cc35..6d42513 100644 --- a/libcxx/include/__charconv/to_chars_integral.h +++ b/libcxx/include/__charconv/to_chars_integral.h @@ -24,6 +24,7 @@ #include <__type_traits/integral_constant.h> #include <__type_traits/is_integral.h> #include <__type_traits/is_same.h> +#include <__type_traits/is_signed.h> #include <__type_traits/make_32_64_or_128_bit.h> #include <__type_traits/make_unsigned.h> #include <__utility/unreachable.h> diff --git a/libcxx/include/__compare/is_eq.h b/libcxx/include/__compare/is_eq.h index 9a82df1..ee4d11b 100644 --- a/libcxx/include/__compare/is_eq.h +++ b/libcxx/include/__compare/is_eq.h @@ -20,12 +20,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_eq(partial_ordering __c) noexcept { return __c == 0; } -_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_neq(partial_ordering __c) noexcept { return __c != 0; } -_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lt(partial_ordering __c) noexcept { return __c < 0; } -_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lteq(partial_ordering __c) noexcept { return __c <= 0; } -_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gt(partial_ordering __c) noexcept { return __c > 0; } -_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexcept { return __c >= 0; } +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_eq(partial_ordering __c) noexcept { return __c == 0; } +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_neq(partial_ordering __c) noexcept { return __c != 0; } +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lt(partial_ordering __c) noexcept { return __c < 0; } +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lteq(partial_ordering __c) noexcept { return __c <= 0; } +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gt(partial_ordering __c) noexcept { return __c > 0; } +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexcept { return __c >= 0; } #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__condition_variable/condition_variable.h b/libcxx/include/__condition_variable/condition_variable.h index 1e8edd5..b715193 100644 --- a/libcxx/include/__condition_variable/condition_variable.h +++ b/libcxx/include/__condition_variable/condition_variable.h @@ -170,7 +170,7 @@ public: wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d, _Predicate __pred); typedef __libcpp_condvar_t* native_handle_type; - _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__cv_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__cv_; } private: void diff --git a/libcxx/include/__config b/libcxx/include/__config index 357f77b..e758acf 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -14,6 +14,8 @@ #include <__configuration/abi.h> #include <__configuration/availability.h> #include <__configuration/compiler.h> +#include <__configuration/experimental.h> +#include <__configuration/hardening.h> #include <__configuration/language.h> #include <__configuration/platform.h> @@ -38,195 +40,6 @@ # define _LIBCPP_FREESTANDING # endif -// NOLINTNEXTLINE(libcpp-cpp-version-check) -# if __cplusplus < 201103L -# define _LIBCPP_CXX03_LANG -# endif - -# if __has_feature(experimental_library) -# ifndef _LIBCPP_ENABLE_EXPERIMENTAL -# define _LIBCPP_ENABLE_EXPERIMENTAL -# endif -# endif - -// Incomplete features get their own specific disabling flags. This makes it -// easier to grep for target specific flags once the feature is complete. -# if defined(_LIBCPP_ENABLE_EXPERIMENTAL) || defined(_LIBCPP_BUILDING_LIBRARY) -# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 1 -# else -# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 0 -# endif - -# define _LIBCPP_HAS_EXPERIMENTAL_PSTL _LIBCPP_HAS_EXPERIMENTAL_LIBRARY -# define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY -# define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY -# define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY - -// HARDENING { - -// TODO(LLVM 23): Remove this. We're making these an error to catch folks who might not have migrated. -// Since hardening went through several changes (many of which impacted user-facing macros), -// we're keeping these checks around for a bit longer than usual. Failure to properly configure -// hardening results in checks being dropped silently, which is a pretty big deal. -# if defined(_LIBCPP_ENABLE_ASSERTIONS) -# error "_LIBCPP_ENABLE_ASSERTIONS has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)" -# endif -# if defined(_LIBCPP_ENABLE_HARDENED_MODE) -# error "_LIBCPP_ENABLE_HARDENED_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)" -# endif -# if defined(_LIBCPP_ENABLE_SAFE_MODE) -# error "_LIBCPP_ENABLE_SAFE_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)" -# endif -# if defined(_LIBCPP_ENABLE_DEBUG_MODE) -# error "_LIBCPP_ENABLE_DEBUG_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)" -# endif - -// The library provides the macro `_LIBCPP_HARDENING_MODE` which can be set to one of the following values: -// -// - `_LIBCPP_HARDENING_MODE_NONE`; -// - `_LIBCPP_HARDENING_MODE_FAST`; -// - `_LIBCPP_HARDENING_MODE_EXTENSIVE`; -// - `_LIBCPP_HARDENING_MODE_DEBUG`. -// -// These values have the following effects: -// -// - `_LIBCPP_HARDENING_MODE_NONE` -- sets the hardening mode to "none" which disables all runtime hardening checks; -// -// - `_LIBCPP_HARDENING_MODE_FAST` -- sets that hardening mode to "fast". The fast mode enables security-critical checks -// that can be done with relatively little runtime overhead in constant time; -// -// - `_LIBCPP_HARDENING_MODE_EXTENSIVE` -- sets the hardening mode to "extensive". The extensive mode is a superset of -// the fast mode that additionally enables checks that are relatively cheap and prevent common types of logic errors -// but are not necessarily security-critical; -// -// - `_LIBCPP_HARDENING_MODE_DEBUG` -- sets the hardening mode to "debug". The debug mode is a superset of the extensive -// mode and enables all checks available in the library, including internal assertions. Checks that are part of the -// debug mode can be very expensive and thus the debug mode is intended to be used for testing, not in production. - -// Inside the library, assertions are categorized so they can be cherry-picked based on the chosen hardening mode. These -// macros are only for internal use -- users should only pick one of the high-level hardening modes described above. -// -// - `_LIBCPP_ASSERT_VALID_INPUT_RANGE` -- checks that ranges (whether expressed as an iterator pair, an iterator and -// a sentinel, an iterator and a count, or a `std::range`) given as input to library functions are valid: -// - the sentinel is reachable from the begin iterator; -// - TODO(hardening): both iterators refer to the same container. -// -// - `_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS` -- checks that any attempts to access a container element, whether through -// the container object or through an iterator, are valid and do not attempt to go out of bounds or otherwise access -// a non-existent element. For iterator checks to work, bounded iterators must be enabled in the ABI. Types like -// `optional` and `function` are considered one-element containers for the purposes of this check. -// -// - `_LIBCPP_ASSERT_NON_NULL` -- checks that the pointer being dereferenced is not null. On most modern platforms zero -// address does not refer to an actual location in memory, so a null pointer dereference would not compromize the -// memory security of a program (however, it is still undefined behavior that can result in strange errors due to -// compiler optimizations). -// -// - `_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES` -- for functions that take several ranges as arguments, checks that the -// given ranges do not overlap. -// -// - `_LIBCPP_ASSERT_VALID_DEALLOCATION` -- checks that an attempt to deallocate memory is valid (e.g. the given object -// was allocated by the given allocator). Violating this category typically results in a memory leak. -// -// - `_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL` -- checks that a call to an external API doesn't fail in -// an unexpected manner. This includes triggering documented cases of undefined behavior in an external library (like -// attempting to unlock an unlocked mutex in pthreads). Any API external to the library falls under this category -// (from system calls to compiler intrinsics). We generally don't expect these failures to compromize memory safety or -// otherwise create an immediate security issue. -// -// - `_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR` -- checks any operations that exchange nodes between containers to make sure -// the containers have compatible allocators. -// -// - `_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN` -- checks that the given argument is within the domain of valid arguments -// for the function. Violating this typically produces an incorrect result (e.g. the clamp algorithm returns the -// original value without clamping it due to incorrect functors) or puts an object into an invalid state (e.g. -// a string view where only a subset of elements is possible to access). This category is for assertions violating -// which doesn't cause any immediate issues in the library -- whatever the consequences are, they will happen in the -// user code. -// -// - `_LIBCPP_ASSERT_PEDANTIC` -- checks prerequisites which are imposed by the Standard, but violating which happens to -// be benign in our implementation. -// -// - `_LIBCPP_ASSERT_SEMANTIC_REQUIREMENT` -- checks that the given argument satisfies the semantic requirements imposed -// by the Standard. Typically, there is no simple way to completely prove that a semantic requirement is satisfied; -// thus, this would often be a heuristic check and it might be quite expensive. -// -// - `_LIBCPP_ASSERT_INTERNAL` -- checks that internal invariants of the library hold. These assertions don't depend on -// user input. -// -// - `_LIBCPP_ASSERT_UNCATEGORIZED` -- for assertions that haven't been properly classified yet. - -// clang-format off -# define _LIBCPP_HARDENING_MODE_NONE (1 << 1) -# define _LIBCPP_HARDENING_MODE_FAST (1 << 2) -# define _LIBCPP_HARDENING_MODE_EXTENSIVE (1 << 4) // Deliberately not ordered. -# define _LIBCPP_HARDENING_MODE_DEBUG (1 << 3) -// clang-format on - -# ifndef _LIBCPP_HARDENING_MODE - -# ifndef _LIBCPP_HARDENING_MODE_DEFAULT -# error _LIBCPP_HARDENING_MODE_DEFAULT is not defined. This definition should be set at configuration time in the \ -`__config_site` header, please make sure your installation of libc++ is not broken. -# endif - -# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEFAULT -# endif - -# if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_NONE && \ - _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_FAST && \ - _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_EXTENSIVE && \ - _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG -# error _LIBCPP_HARDENING_MODE must be set to one of the following values: \ -_LIBCPP_HARDENING_MODE_NONE, \ -_LIBCPP_HARDENING_MODE_FAST, \ -_LIBCPP_HARDENING_MODE_EXTENSIVE, \ -_LIBCPP_HARDENING_MODE_DEBUG -# endif - -// Hardening assertion semantics generally mirror the evaluation semantics of C++26 Contracts: -// - `ignore` evaluates the assertion but doesn't do anything if it fails (note that it differs from the Contracts -// `ignore` semantic which wouldn't evaluate the assertion at all); -// - `observe` logs an error (indicating, if possible, that the error is fatal) and continues execution; -// - `quick-enforce` terminates the program as fast as possible (via trapping); -// - `enforce` logs an error and then terminates the program. -// -// Notes: -// - Continuing execution after a hardening check fails results in undefined behavior; the `observe` semantic is meant -// to make adopting hardening easier but should not be used outside of this scenario; -// - C++26 wording for Library Hardening precludes a conforming Hardened implementation from using the Contracts -// `ignore` semantic when evaluating hardened preconditions in the Library. Libc++ allows using this semantic for -// hardened preconditions, however, be aware that using `ignore` does not produce a conforming "Hardened" -// implementation, unlike the other semantics above. -// clang-format off -# define _LIBCPP_ASSERTION_SEMANTIC_IGNORE (1 << 1) -# define _LIBCPP_ASSERTION_SEMANTIC_OBSERVE (1 << 2) -# define _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE (1 << 3) -# define _LIBCPP_ASSERTION_SEMANTIC_ENFORCE (1 << 4) -// clang-format on - -// Allow users to define an arbitrary assertion semantic; otherwise, use the default mapping from modes to semantics. -// The default is for production-capable modes to use `quick-enforce` (i.e., trap) and for the `debug` mode to use -// `enforce` (i.e., log and abort). -# ifndef _LIBCPP_ASSERTION_SEMANTIC - -# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG -# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_ENFORCE -# else -# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE -# endif - -# else -# if !_LIBCPP_HAS_EXPERIMENTAL_LIBRARY -# error "Assertion semantics are an experimental feature." -# endif -# if defined(_LIBCPP_CXX03_LANG) -# error "Assertion semantics are not available in the C++03 mode." -# endif - -# endif // _LIBCPP_ASSERTION_SEMANTIC - -// } HARDENING - # define _LIBCPP_TOSTRING2(x) #x # define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x) @@ -339,7 +152,7 @@ _LIBCPP_HARDENING_MODE_DEBUG # ifndef _LIBCPP_CXX03_LANG -# define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp) +# define _LIBCPP_ALIGNOF(...) alignof(__VA_ARGS__) # define _ALIGNAS_TYPE(x) alignas(x) # define _ALIGNAS(x) alignas(x) # define _NOEXCEPT noexcept @@ -348,7 +161,7 @@ _LIBCPP_HARDENING_MODE_DEBUG # else -# define _LIBCPP_ALIGNOF(_Tp) _Alignof(_Tp) +# define _LIBCPP_ALIGNOF(...) _Alignof(__VA_ARGS__) # define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x)))) # define _ALIGNAS(x) __attribute__((__aligned__(x))) # define nullptr __nullptr @@ -478,6 +291,16 @@ typedef __char32_t char32_t; # define _LIBCPP_HARDENING_SIG n // "none" # endif +# if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_OBSERVE +# define _LIBCPP_ASSERTION_SEMANTIC_SIG o +# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE +# define _LIBCPP_ASSERTION_SEMANTIC_SIG q +# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE +# define _LIBCPP_ASSERTION_SEMANTIC_SIG e +# else +# define _LIBCPP_ASSERTION_SEMANTIC_SIG i // `ignore` +# endif + # if !_LIBCPP_HAS_EXCEPTIONS # define _LIBCPP_EXCEPTIONS_SIG n # else @@ -485,7 +308,9 @@ typedef __char32_t char32_t; # endif # define _LIBCPP_ODR_SIGNATURE \ - _LIBCPP_CONCAT(_LIBCPP_CONCAT(_LIBCPP_HARDENING_SIG, _LIBCPP_EXCEPTIONS_SIG), _LIBCPP_VERSION) + _LIBCPP_CONCAT( \ + _LIBCPP_CONCAT(_LIBCPP_CONCAT(_LIBCPP_HARDENING_SIG, _LIBCPP_ASSERTION_SEMANTIC_SIG), _LIBCPP_EXCEPTIONS_SIG), \ + _LIBCPP_VERSION) // This macro marks a symbol as being hidden from libc++'s ABI. This is achieved // on two levels: @@ -670,27 +495,6 @@ typedef __char32_t char32_t; # define _LIBCPP_HAS_ALIGNED_ALLOCATION 1 # endif -// It is not yet possible to use aligned_alloc() on all Apple platforms since -// 10.15 was the first version to ship an implementation of aligned_alloc(). -# if defined(__APPLE__) -# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ - __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) || \ - (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \ - __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \ - (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && \ - __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000) || \ - (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000) -# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 0 -# else -# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 1 -# endif -# elif defined(__ANDROID__) && __ANDROID_API__ < 28 -// Android only provides aligned_alloc when targeting API 28 or higher. -# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 0 -# else -# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 1 -# endif - # if defined(__APPLE__) || defined(__FreeBSD__) # define _LIBCPP_WCTYPE_IS_MASK # endif @@ -721,6 +525,15 @@ typedef __char32_t char32_t; # define _LIBCPP_DEPRECATED_(m) # endif +// FIXME: using `#warning` causes diagnostics from system headers which include deprecated headers. This can only be +// enabled again once https://github.com/llvm/llvm-project/pull/168041 (or a similar feature) has landed, since that +// allows suppression in system headers. +# if defined(__DEPRECATED) && __DEPRECATED && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && 0 +# define _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS 1 +# else +# define _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS 0 +# endif + # if !defined(_LIBCPP_CXX03_LANG) # define _LIBCPP_DEPRECATED_IN_CXX11 _LIBCPP_DEPRECATED # else @@ -844,18 +657,10 @@ typedef __char32_t char32_t; # endif // _LIBCPP_HAS_THREAD_API # endif // _LIBCPP_HAS_THREADS -# if _LIBCPP_HAS_THREAD_API_PTHREAD -# if defined(__ANDROID__) && __ANDROID_API__ >= 30 -# define _LIBCPP_HAS_COND_CLOCKWAIT 1 -# elif defined(_LIBCPP_GLIBC_PREREQ) -# if _LIBCPP_GLIBC_PREREQ(2, 30) -# define _LIBCPP_HAS_COND_CLOCKWAIT 1 -# else -# define _LIBCPP_HAS_COND_CLOCKWAIT 0 -# endif -# else -# define _LIBCPP_HAS_COND_CLOCKWAIT 0 -# endif +# if !_LIBCPP_HAS_THREAD_API_PTHREAD +# define _LIBCPP_HAS_COND_CLOCKWAIT 0 +# elif (defined(__ANDROID__) && __ANDROID_API__ >= 30) || _LIBCPP_GLIBC_PREREQ(2, 30) +# define _LIBCPP_HAS_COND_CLOCKWAIT 1 # else # define _LIBCPP_HAS_COND_CLOCKWAIT 0 # endif @@ -1021,12 +826,8 @@ typedef __char32_t char32_t; // the latter depends on internal GNU libc details that are not appropriate // to depend on here, so any declarations present when __cpp_char8_t is not // defined are ignored. -# if defined(_LIBCPP_GLIBC_PREREQ) -# if _LIBCPP_GLIBC_PREREQ(2, 36) && defined(__cpp_char8_t) -# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1 -# else -# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0 -# endif +# if _LIBCPP_GLIBC_PREREQ(2, 36) && defined(__cpp_char8_t) +# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1 # else # define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0 # endif diff --git a/libcxx/include/__config_site.in b/libcxx/include/__config_site.in index b68c0c8..b09ca807 100644 --- a/libcxx/include/__config_site.in +++ b/libcxx/include/__config_site.in @@ -40,6 +40,11 @@ // Hardening. #cmakedefine _LIBCPP_HARDENING_MODE_DEFAULT @_LIBCPP_HARDENING_MODE_DEFAULT@ +#cmakedefine _LIBCPP_ASSERTION_SEMANTIC_DEFAULT @_LIBCPP_ASSERTION_SEMANTIC_DEFAULT@ + +// C libraries +#cmakedefine01 _LIBCPP_LIBC_PICOLIBC +#cmakedefine01 _LIBCPP_LIBC_NEWLIB // __USE_MINGW_ANSI_STDIO gets redefined on MinGW #ifdef __clang__ diff --git a/libcxx/include/__configuration/abi.h b/libcxx/include/__configuration/abi.h index 38b85c6..f30d0a5 100644 --- a/libcxx/include/__configuration/abi.h +++ b/libcxx/include/__configuration/abi.h @@ -63,6 +63,7 @@ // These flags are documented in ABIGuarantees.rst # define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT +# define _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE # define _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON # define _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON # define _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10 diff --git a/libcxx/include/__configuration/availability.h b/libcxx/include/__configuration/availability.h index 5433df8..a5bd266 100644 --- a/libcxx/include/__configuration/availability.h +++ b/libcxx/include/__configuration/availability.h @@ -17,55 +17,10 @@ # pragma GCC system_header #endif -// Libc++ is shipped by various vendors. In particular, it is used as a system -// library on macOS, iOS and other Apple platforms. In order for users to be -// able to compile a binary that is intended to be deployed to an older version -// of a platform, Clang provides availability attributes [1]. These attributes -// can be placed on declarations and are used to describe the life cycle of a -// symbol in the library. -// -// The main goal is to ensure a compile-time error if a symbol that hasn't been -// introduced in a previously released library is used in a program that targets -// that previously released library. Normally, this would be a load-time error -// when one tries to launch the program against the older library. -// -// For example, the filesystem library was introduced in the dylib in LLVM 9. -// On Apple platforms, this corresponds to macOS 10.15. If a user compiles on -// a macOS 10.15 host but targets macOS 10.13 with their program, the compiler -// would normally not complain (because the required declarations are in the -// headers), but the dynamic loader would fail to find the symbols when actually -// trying to launch the program on macOS 10.13. To turn this into a compile-time -// issue instead, declarations are annotated with when they were introduced, and -// the compiler can produce a diagnostic if the program references something that -// isn't available on the deployment target. -// -// This mechanism is general in nature, and any vendor can add their markup to -// the library (see below). Whenever a new feature is added that requires support -// in the shared library, two macros are added below to allow marking the feature -// as unavailable: -// 1. A macro named `_LIBCPP_AVAILABILITY_HAS_<feature>` which must be defined -// to `_LIBCPP_INTRODUCED_IN_<version>` for the appropriate LLVM version. -// 2. A macro named `_LIBCPP_AVAILABILITY_<feature>`, which must be defined to -// `_LIBCPP_INTRODUCED_IN_<version>_MARKUP` for the appropriate LLVM version. -// -// When vendors decide to ship the feature as part of their shared library, they -// can update the `_LIBCPP_INTRODUCED_IN_<version>` macro (and the markup counterpart) -// based on the platform version they shipped that version of LLVM in. The library -// will then use this markup to provide an optimal user experience on these platforms. -// -// Furthermore, many features in the standard library have corresponding -// feature-test macros. The `_LIBCPP_AVAILABILITY_HAS_<feature>` macros -// are checked by the corresponding feature-test macros generated by -// generate_feature_test_macro_components.py to ensure that the library -// doesn't announce a feature as being implemented if it is unavailable on -// the deployment target. -// -// Note that this mechanism is disabled by default in the "upstream" libc++. -// Availability annotations are only meaningful when shipping libc++ inside -// a platform (i.e. as a system library), and so vendors that want them should -// turn those annotations on at CMake configuration time. -// -// [1]: https://clang.llvm.org/docs/AttributeReference.html#availability +// This file defines a framework that can be used by vendors to encode the version of an operating system that various +// features of libc++ has been shipped in. This is primarily intended to allow safely deploying an executable built with +// a new version of the library on a platform containing an older version of the built library. +// Detailed documentation for this can be found at https://libcxx.llvm.org/VendorDocumentation.html#availability-markup // Availability markup is disabled when building the library, or when a non-Clang // compiler is used because only Clang supports the necessary attributes. @@ -84,6 +39,9 @@ // in all versions of the library are available. #if !_LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS +# define _LIBCPP_INTRODUCED_IN_LLVM_22 1 +# define _LIBCPP_INTRODUCED_IN_LLVM_22_ATTRIBUTE /* nothing */ + # define _LIBCPP_INTRODUCED_IN_LLVM_21 1 # define _LIBCPP_INTRODUCED_IN_LLVM_21_ATTRIBUTE /* nothing */ @@ -112,6 +70,11 @@ // clang-format off +// LLVM 22 +// TODO: Fill this in +# define _LIBCPP_INTRODUCED_IN_LLVM_22 0 +# define _LIBCPP_INTRODUCED_IN_LLVM_22_ATTRIBUTE __attribute__((unavailable)) + // LLVM 21 // TODO: Fill this in # define _LIBCPP_INTRODUCED_IN_LLVM_21 0 @@ -242,6 +205,13 @@ #endif +// This controls the availability of new implementation of std::atomic's +// wait, notify_one and notify_all. The new implementation uses +// the native atomic wait/notify operations on platforms that support them +// based on the size of the atomic type, instead of the type itself. +#define _LIBCPP_AVAILABILITY_HAS_NEW_SYNC _LIBCPP_INTRODUCED_IN_LLVM_22 +#define _LIBCPP_AVAILABILITY_NEW_SYNC _LIBCPP_INTRODUCED_IN_LLVM_22_ATTRIBUTE + // Enable additional explicit instantiations of iostreams components. This // reduces the number of weak definitions generated in programs that use // iostreams by providing a single strong definition in the shared library. diff --git a/libcxx/include/__configuration/experimental.h b/libcxx/include/__configuration/experimental.h new file mode 100644 index 0000000..d14df3e --- /dev/null +++ b/libcxx/include/__configuration/experimental.h @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONFIGURATION_EXPERIMENTAL_H +#define _LIBCPP___CONFIGURATION_EXPERIMENTAL_H + +#include <__config_site> + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +#if __has_feature(experimental_library) +# ifndef _LIBCPP_ENABLE_EXPERIMENTAL +# define _LIBCPP_ENABLE_EXPERIMENTAL +# endif +#endif + +// Incomplete features get their own specific disabling flags. This makes it +// easier to grep for target specific flags once the feature is complete. +#if defined(_LIBCPP_ENABLE_EXPERIMENTAL) || defined(_LIBCPP_BUILDING_LIBRARY) +# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 1 +#else +# define _LIBCPP_HAS_EXPERIMENTAL_LIBRARY 0 +#endif + +#define _LIBCPP_HAS_EXPERIMENTAL_PSTL _LIBCPP_HAS_EXPERIMENTAL_LIBRARY +#define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY +#define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY +#define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY + +#endif // _LIBCPP___CONFIGURATION_EXPERIMENTAL_H diff --git a/libcxx/include/__configuration/hardening.h b/libcxx/include/__configuration/hardening.h new file mode 100644 index 0000000..5723f5a --- /dev/null +++ b/libcxx/include/__configuration/hardening.h @@ -0,0 +1,215 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONFIGURATION_HARDENING_H +#define _LIBCPP___CONFIGURATION_HARDENING_H + +#include <__config_site> +#include <__configuration/experimental.h> +#include <__configuration/language.h> + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +// TODO(LLVM 23): Remove this. We're making these an error to catch folks who might not have migrated. +// Since hardening went through several changes (many of which impacted user-facing macros), +// we're keeping these checks around for a bit longer than usual. Failure to properly configure +// hardening results in checks being dropped silently, which is a pretty big deal. +#if defined(_LIBCPP_ENABLE_ASSERTIONS) +# error "_LIBCPP_ENABLE_ASSERTIONS has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)" +#endif +#if defined(_LIBCPP_ENABLE_HARDENED_MODE) +# error "_LIBCPP_ENABLE_HARDENED_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)" +#endif +#if defined(_LIBCPP_ENABLE_SAFE_MODE) +# error "_LIBCPP_ENABLE_SAFE_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)" +#endif +#if defined(_LIBCPP_ENABLE_DEBUG_MODE) +# error "_LIBCPP_ENABLE_DEBUG_MODE has been removed, please use _LIBCPP_HARDENING_MODE=<mode> instead (see docs)" +#endif + +// The library provides the macro `_LIBCPP_HARDENING_MODE` which can be set to one of the following values: +// +// - `_LIBCPP_HARDENING_MODE_NONE`; +// - `_LIBCPP_HARDENING_MODE_FAST`; +// - `_LIBCPP_HARDENING_MODE_EXTENSIVE`; +// - `_LIBCPP_HARDENING_MODE_DEBUG`. +// +// These values have the following effects: +// +// - `_LIBCPP_HARDENING_MODE_NONE` -- sets the hardening mode to "none" which disables all runtime hardening checks; +// +// - `_LIBCPP_HARDENING_MODE_FAST` -- sets that hardening mode to "fast". The fast mode enables security-critical checks +// that can be done with relatively little runtime overhead in constant time; +// +// - `_LIBCPP_HARDENING_MODE_EXTENSIVE` -- sets the hardening mode to "extensive". The extensive mode is a superset of +// the fast mode that additionally enables checks that are relatively cheap and prevent common types of logic errors +// but are not necessarily security-critical; +// +// - `_LIBCPP_HARDENING_MODE_DEBUG` -- sets the hardening mode to "debug". The debug mode is a superset of the extensive +// mode and enables all checks available in the library, including internal assertions. Checks that are part of the +// debug mode can be very expensive and thus the debug mode is intended to be used for testing, not in production. + +// Inside the library, assertions are categorized so they can be cherry-picked based on the chosen hardening mode. These +// macros are only for internal use -- users should only pick one of the high-level hardening modes described above. +// +// - `_LIBCPP_ASSERT_VALID_INPUT_RANGE` -- checks that ranges (whether expressed as an iterator pair, an iterator and +// a sentinel, an iterator and a count, or a `std::range`) given as input to library functions are valid: +// - the sentinel is reachable from the begin iterator; +// - TODO(hardening): both iterators refer to the same container. +// +// - `_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS` -- checks that any attempts to access a container element, whether through +// the container object or through an iterator, are valid and do not attempt to go out of bounds or otherwise access +// a non-existent element. For iterator checks to work, bounded iterators must be enabled in the ABI. Types like +// `optional` and `function` are considered one-element containers for the purposes of this check. +// +// - `_LIBCPP_ASSERT_NON_NULL` -- checks that the pointer being dereferenced is not null. On most modern platforms zero +// address does not refer to an actual location in memory, so a null pointer dereference would not compromize the +// memory security of a program (however, it is still undefined behavior that can result in strange errors due to +// compiler optimizations). +// +// - `_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES` -- for functions that take several ranges as arguments, checks that the +// given ranges do not overlap. +// +// - `_LIBCPP_ASSERT_VALID_DEALLOCATION` -- checks that an attempt to deallocate memory is valid (e.g. the given object +// was allocated by the given allocator). Violating this category typically results in a memory leak. +// +// - `_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL` -- checks that a call to an external API doesn't fail in +// an unexpected manner. This includes triggering documented cases of undefined behavior in an external library (like +// attempting to unlock an unlocked mutex in pthreads). Any API external to the library falls under this category +// (from system calls to compiler intrinsics). We generally don't expect these failures to compromize memory safety or +// otherwise create an immediate security issue. +// +// - `_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR` -- checks any operations that exchange nodes between containers to make sure +// the containers have compatible allocators. +// +// - `_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN` -- checks that the given argument is within the domain of valid arguments +// for the function. Violating this typically produces an incorrect result (e.g. the clamp algorithm returns the +// original value without clamping it due to incorrect functors) or puts an object into an invalid state (e.g. +// a string view where only a subset of elements is possible to access). This category is for assertions violating +// which doesn't cause any immediate issues in the library -- whatever the consequences are, they will happen in the +// user code. +// +// - `_LIBCPP_ASSERT_PEDANTIC` -- checks prerequisites which are imposed by the Standard, but violating which happens to +// be benign in our implementation. +// +// - `_LIBCPP_ASSERT_SEMANTIC_REQUIREMENT` -- checks that the given argument satisfies the semantic requirements imposed +// by the Standard. Typically, there is no simple way to completely prove that a semantic requirement is satisfied; +// thus, this would often be a heuristic check and it might be quite expensive. +// +// - `_LIBCPP_ASSERT_INTERNAL` -- checks that internal invariants of the library hold. These assertions don't depend on +// user input. +// +// - `_LIBCPP_ASSERT_UNCATEGORIZED` -- for assertions that haven't been properly classified yet. + +// clang-format off +# define _LIBCPP_HARDENING_MODE_NONE (1 << 1) +# define _LIBCPP_HARDENING_MODE_FAST (1 << 2) +# define _LIBCPP_HARDENING_MODE_EXTENSIVE (1 << 4) // Deliberately not ordered. +# define _LIBCPP_HARDENING_MODE_DEBUG (1 << 3) +// clang-format on + +#ifndef _LIBCPP_HARDENING_MODE + +# ifndef _LIBCPP_HARDENING_MODE_DEFAULT +# error _LIBCPP_HARDENING_MODE_DEFAULT is not defined. This definition should be set at configuration time in the \ +`__config_site` header, please make sure your installation of libc++ is not broken. +# endif + +# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEFAULT +#endif + +#if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_NONE && _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_FAST && \ + _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_EXTENSIVE && \ + _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG +# error _LIBCPP_HARDENING_MODE must be set to one of the following values: \ +_LIBCPP_HARDENING_MODE_NONE, \ +_LIBCPP_HARDENING_MODE_FAST, \ +_LIBCPP_HARDENING_MODE_EXTENSIVE, \ +_LIBCPP_HARDENING_MODE_DEBUG +#endif + +// The library provides the macro `_LIBCPP_ASSERTION_SEMANTIC` for configuring the assertion semantic used by hardening; +// it can be set to one of the following values: +// +// - `_LIBCPP_ASSERTION_SEMANTIC_IGNORE`; +// - `_LIBCPP_ASSERTION_SEMANTIC_OBSERVE`; +// - `_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE`; +// - `_LIBCPP_ASSERTION_SEMANTIC_ENFORCE`. +// +// libc++ assertion semantics generally mirror the evaluation semantics of C++26 Contracts: +// - `ignore` evaluates the assertion but doesn't do anything if it fails (note that it differs from the Contracts +// `ignore` semantic which wouldn't evaluate the assertion at all); +// - `observe` logs an error (indicating, if possible, that the error is fatal) and continues execution; +// - `quick-enforce` terminates the program as fast as possible (via trapping); +// - `enforce` logs an error and then terminates the program. +// +// Additionally, a special `hardening-dependent` value selects the assertion semantic based on the hardening mode in +// effect: the production-capable modes (`fast` and `extensive`) map to `quick_enforce` and the `debug` mode maps to +// `enforce`. The `hardening-dependent` semantic cannot be selected explicitly, it is only used when no assertion +// semantic is provided by the user _and_ the library's default semantic is configured to be dependent on hardening. +// +// Notes: +// - Continuing execution after a hardening check fails results in undefined behavior; the `observe` semantic is meant +// to make adopting hardening easier but should not be used outside of this scenario; +// - C++26 wording for Library Hardening precludes a conforming Hardened implementation from using the Contracts +// `ignore` semantic when evaluating hardened preconditions in the Library. Libc++ allows using this semantic for +// hardened preconditions, however, be aware that using `ignore` does not produce a conforming "Hardened" +// implementation, unlike the other semantics above. +// clang-format off +# define _LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT (1 << 1) +# define _LIBCPP_ASSERTION_SEMANTIC_IGNORE (1 << 2) +# define _LIBCPP_ASSERTION_SEMANTIC_OBSERVE (1 << 3) +# define _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE (1 << 4) +# define _LIBCPP_ASSERTION_SEMANTIC_ENFORCE (1 << 5) +// clang-format on + +// If the user attempts to configure the assertion semantic, check that it is allowed in the current environment. +#if defined(_LIBCPP_ASSERTION_SEMANTIC) +# if !_LIBCPP_HAS_EXPERIMENTAL_LIBRARY +# error "Assertion semantics are an experimental feature." +# endif +# if defined(_LIBCPP_CXX03_LANG) +# error "Assertion semantics are not available in the C++03 mode." +# endif +#endif // defined(_LIBCPP_ASSERTION_SEMANTIC) + +// User-provided semantic takes top priority -- don't override if set. +#ifndef _LIBCPP_ASSERTION_SEMANTIC + +# ifndef _LIBCPP_ASSERTION_SEMANTIC_DEFAULT +# error _LIBCPP_ASSERTION_SEMANTIC_DEFAULT is not defined. This definition should be set at configuration time in \ +the `__config_site` header, please make sure your installation of libc++ is not broken. +# endif + +# if _LIBCPP_ASSERTION_SEMANTIC_DEFAULT != _LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT +# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_DEFAULT +# else +# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG +# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_ENFORCE +# else +# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE +# endif +# endif // _LIBCPP_ASSERTION_SEMANTIC_DEFAULT != _LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT + +#endif // #ifndef _LIBCPP_ASSERTION_SEMANTIC + +// Finally, validate the selected semantic (in case the user tries setting it to an incorrect value): +#if _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_IGNORE && \ + _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_OBSERVE && \ + _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE && \ + _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_ENFORCE +# error _LIBCPP_ASSERTION_SEMANTIC must be set to one of the following values: \ +_LIBCPP_ASSERTION_SEMANTIC_IGNORE, \ +_LIBCPP_ASSERTION_SEMANTIC_OBSERVE, \ +_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE, \ +_LIBCPP_ASSERTION_SEMANTIC_ENFORCE +#endif + +#endif // _LIBCPP___CONFIGURATION_HARDENING_H diff --git a/libcxx/include/__configuration/language.h b/libcxx/include/__configuration/language.h index 9c224dfa..26e87f8 100644 --- a/libcxx/include/__configuration/language.h +++ b/libcxx/include/__configuration/language.h @@ -18,6 +18,9 @@ // NOLINTBEGIN(libcpp-cpp-version-check) #ifdef __cplusplus +# if __cplusplus < 201103L +# define _LIBCPP_CXX03_LANG +# endif # if __cplusplus <= 201103L # define _LIBCPP_STD_VER 11 # elif __cplusplus <= 201402L diff --git a/libcxx/include/__configuration/platform.h b/libcxx/include/__configuration/platform.h index f3c199d..644fe17 100644 --- a/libcxx/include/__configuration/platform.h +++ b/libcxx/include/__configuration/platform.h @@ -31,22 +31,15 @@ #endif // Need to detect which libc we're using if we're on Linux. -#if defined(__linux__) || defined(__AMDGPU__) || defined(__NVPTX__) -# if __has_include(<features.h>) -# include <features.h> -# if defined(__GLIBC_PREREQ) -# define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b) -# else -# define _LIBCPP_GLIBC_PREREQ(a, b) 0 -# endif // defined(__GLIBC_PREREQ) -# endif -#endif - -// This is required in order for _NEWLIB_VERSION to be defined in places where we use it. -// TODO: We shouldn't be including arbitrarily-named headers from libc++ since this can break valid -// user code. Move code paths that need _NEWLIB_VERSION to another customization mechanism. -#if __has_include(<picolibc.h>) -# include <picolibc.h> +#if (defined(__linux__) || defined(__AMDGPU__) || defined(__NVPTX__)) && __has_include(<features.h>) +# include <features.h> +# if defined(__GLIBC_PREREQ) +# define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b) +# else +# define _LIBCPP_GLIBC_PREREQ(a, b) 0 +# endif // defined(__GLIBC_PREREQ) +#else +# define _LIBCPP_GLIBC_PREREQ(a, b) 0 #endif #ifndef __BYTE_ORDER__ diff --git a/libcxx/include/__coroutine/coroutine_handle.h b/libcxx/include/__coroutine/coroutine_handle.h index b7add25..b26a650 100644 --- a/libcxx/include/__coroutine/coroutine_handle.h +++ b/libcxx/include/__coroutine/coroutine_handle.h @@ -44,9 +44,9 @@ public: } // [coroutine.handle.export.import], export/import - _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; } - _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept { coroutine_handle __tmp; __tmp.__handle_ = __addr; return __tmp; @@ -55,7 +55,7 @@ public: // [coroutine.handle.observers], observers _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; } - _LIBCPP_HIDE_FROM_ABI bool done() const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool done() const { _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "done() can be called only on suspended coroutines"); return __builtin_coro_done(__handle_); } @@ -100,7 +100,7 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr coroutine_handle(nullptr_t) noexcept {} - _LIBCPP_HIDE_FROM_ABI static coroutine_handle from_promise(_Promise& __promise) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static coroutine_handle from_promise(_Promise& __promise) { using _RawPromise = __remove_cv_t<_Promise>; coroutine_handle __tmp; __tmp.__handle_ = @@ -114,9 +114,9 @@ public: } // [coroutine.handle.export.import], export/import - _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; } - _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept { coroutine_handle __tmp; __tmp.__handle_ = __addr; return __tmp; @@ -130,7 +130,7 @@ public: // [coroutine.handle.observers], observers _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; } - _LIBCPP_HIDE_FROM_ABI bool done() const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool done() const { _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "done() can be called only on suspended coroutines"); return __builtin_coro_done(__handle_); } @@ -150,7 +150,7 @@ public: } // [coroutine.handle.promise], promise access - _LIBCPP_HIDE_FROM_ABI _Promise& promise() const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Promise& promise() const { return *static_cast<_Promise*>(__builtin_coro_promise(this->__handle_, alignof(_Promise), false)); } @@ -165,7 +165,7 @@ private: // [coroutine.handle.hash] template <class _Tp> struct hash<coroutine_handle<_Tp>> { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept { return hash<void*>()(__v.address()); } }; diff --git a/libcxx/include/__coroutine/noop_coroutine_handle.h b/libcxx/include/__coroutine/noop_coroutine_handle.h index 692398a..b9c54d3 100644 --- a/libcxx/include/__coroutine/noop_coroutine_handle.h +++ b/libcxx/include/__coroutine/noop_coroutine_handle.h @@ -35,7 +35,7 @@ public: // [coroutine.handle.noop.observers], observers _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return true; } - _LIBCPP_HIDE_FROM_ABI constexpr bool done() const noexcept { return false; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool done() const noexcept { return false; } // [coroutine.handle.noop.resumption], resumption _LIBCPP_HIDE_FROM_ABI constexpr void operator()() const noexcept {} @@ -43,13 +43,13 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr void destroy() const noexcept {} // [coroutine.handle.noop.promise], promise access - _LIBCPP_HIDE_FROM_ABI noop_coroutine_promise& promise() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI noop_coroutine_promise& promise() const noexcept { return *static_cast<noop_coroutine_promise*>( __builtin_coro_promise(this->__handle_, alignof(noop_coroutine_promise), false)); } // [coroutine.handle.noop.address], address - _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; } private: _LIBCPP_HIDE_FROM_ABI friend coroutine_handle<noop_coroutine_promise> noop_coroutine() noexcept; @@ -86,7 +86,9 @@ inline noop_coroutine_handle::__noop_coroutine_frame_ty_ noop_coroutine_handle:: # endif // [coroutine.noop.coroutine] -inline _LIBCPP_HIDE_FROM_ABI noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); } +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI noop_coroutine_handle noop_coroutine() noexcept { + return noop_coroutine_handle(); +} _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__cxx03/__fwd/ios.h b/libcxx/include/__cxx03/__fwd/ios.h index dc03e8c..3b33b25b 100644 --- a/libcxx/include/__cxx03/__fwd/ios.h +++ b/libcxx/include/__cxx03/__fwd/ios.h @@ -31,7 +31,7 @@ using wios = basic_ios<wchar_t>; template <class _CharT, class _Traits> class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wios)) basic_ios; -#if defined(_NEWLIB_VERSION) +#if _LIBCPP_LIBC_NEWLIB // On newlib, off_t is 'long int' using streamoff = long int; // for char_traits in <string> #else diff --git a/libcxx/include/__cxx03/__locale b/libcxx/include/__cxx03/__locale index 70dd1e6..e9cbc1f 100644 --- a/libcxx/include/__cxx03/__locale +++ b/libcxx/include/__cxx03/__locale @@ -384,7 +384,7 @@ public: static const mask xdigit = _ISXDIGIT; static const mask blank = _ISBLANK; static const mask __regex_word = 0x8000; -#elif defined(_NEWLIB_VERSION) +#elif _LIBCPP_LIBC_NEWLIB // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h. typedef char mask; // In case char is signed, static_cast is needed to avoid warning on diff --git a/libcxx/include/__cxx03/__locale_dir/locale_base_api.h b/libcxx/include/__cxx03/__locale_dir/locale_base_api.h index a20f095..3dbce82 100644 --- a/libcxx/include/__cxx03/__locale_dir/locale_base_api.h +++ b/libcxx/include/__cxx03/__locale_dir/locale_base_api.h @@ -17,7 +17,7 @@ # include <__cxx03/__locale_dir/locale_base_api/android.h> #elif defined(__sun__) # include <__cxx03/__locale_dir/locale_base_api/solaris.h> -#elif defined(_NEWLIB_VERSION) +#elif _LIBCPP_LIBC_NEWLIB # include <__cxx03/__locale_dir/locale_base_api/newlib.h> #elif defined(__OpenBSD__) # include <__cxx03/__locale_dir/locale_base_api/openbsd.h> diff --git a/libcxx/include/__cxx03/fstream b/libcxx/include/__cxx03/fstream index 65c2c3e..124619c 100644 --- a/libcxx/include/__cxx03/fstream +++ b/libcxx/include/__cxx03/fstream @@ -210,7 +210,7 @@ typedef basic_fstream<wchar_t> wfstream; _LIBCPP_PUSH_MACROS #include <__cxx03/__undef_macros> -#if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION) +#if defined(_LIBCPP_MSVCRT) || _LIBCPP_LIBC_NEWLIB # define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS #endif diff --git a/libcxx/include/__cxx03/locale b/libcxx/include/__cxx03/locale index 79cd50e..4771539 100644 --- a/libcxx/include/__cxx03/locale +++ b/libcxx/include/__cxx03/locale @@ -220,7 +220,7 @@ template <class charT> class messages_byname; # if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) // Most unix variants have catopen. These are the specific ones that don't. -# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__EMSCRIPTEN__) +# if !defined(__BIONIC__) && !_LIBCPP_LIBC_NEWLIB && !defined(__EMSCRIPTEN__) # define _LIBCPP_HAS_CATOPEN 1 # include <nl_types.h> # endif diff --git a/libcxx/include/__cxx03/regex b/libcxx/include/__cxx03/regex index b6a78f2..bbd6eee 100644 --- a/libcxx/include/__cxx03/regex +++ b/libcxx/include/__cxx03/regex @@ -984,7 +984,7 @@ public: typedef _CharT char_type; typedef basic_string<char_type> string_type; typedef locale locale_type; -#if defined(__BIONIC__) || defined(_NEWLIB_VERSION) +#if defined(__BIONIC__) || _LIBCPP_LIBC_NEWLIB // Originally bionic's ctype_base used its own ctype masks because the // builtin ctype implementation wasn't in libc++ yet. Bionic's ctype mask // was only 8 bits wide and already saturated, so it used a wider type here @@ -993,9 +993,7 @@ public: // implementation, but this was not updated to match. Since then Android has // needed to maintain a stable libc++ ABI, and this can't be changed without // an ABI break. - // We also need this workaround for newlib since _NEWLIB_VERSION is not - // defined yet inside __config, so we can't set the - // _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE macro. Additionally, newlib is + // We also need this workaround for newlib since newlib is // often used for space constrained environments, so it makes sense not to // duplicate the ctype table. typedef uint16_t char_class_type; diff --git a/libcxx/include/__exception/exception.h b/libcxx/include/__exception/exception.h index 161cc49..ddc34b0 100644 --- a/libcxx/include/__exception/exception.h +++ b/libcxx/include/__exception/exception.h @@ -54,7 +54,9 @@ public: virtual ~exception() _NOEXCEPT {} - virtual char const* what() const _NOEXCEPT { return __data_._What ? __data_._What : "Unknown exception"; } + [[__nodiscard__]] virtual char const* what() const _NOEXCEPT { + return __data_._What ? __data_._What : "Unknown exception"; + } private: __std_exception_data __data_; @@ -76,7 +78,7 @@ public: _LIBCPP_HIDE_FROM_ABI exception& operator=(const exception&) _NOEXCEPT = default; virtual ~exception() _NOEXCEPT; - virtual const char* what() const _NOEXCEPT; + [[__nodiscard__]] virtual const char* what() const _NOEXCEPT; }; class _LIBCPP_EXPORTED_FROM_ABI bad_exception : public exception { @@ -85,7 +87,7 @@ public: _LIBCPP_HIDE_FROM_ABI bad_exception(const bad_exception&) _NOEXCEPT = default; _LIBCPP_HIDE_FROM_ABI bad_exception& operator=(const bad_exception&) _NOEXCEPT = default; ~bad_exception() _NOEXCEPT override; - const char* what() const _NOEXCEPT override; + [[__nodiscard__]] const char* what() const _NOEXCEPT override; }; #endif // !_LIBCPP_ABI_VCRUNTIME diff --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h index aef036a..92ff5c7 100644 --- a/libcxx/include/__exception/exception_ptr.h +++ b/libcxx/include/__exception/exception_ptr.h @@ -75,9 +75,7 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr { public: // exception_ptr is basically a COW string so it is trivially relocatable. - // It is also replaceable because assignment has normal value semantics. using __trivially_relocatable _LIBCPP_NODEBUG = exception_ptr; - using __replaceable _LIBCPP_NODEBUG = exception_ptr; _LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {} _LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {} diff --git a/libcxx/include/__exception/nested_exception.h b/libcxx/include/__exception/nested_exception.h index dc3266a..dd84efb 100644 --- a/libcxx/include/__exception/nested_exception.h +++ b/libcxx/include/__exception/nested_exception.h @@ -40,7 +40,7 @@ public: // access functions [[__noreturn__]] void rethrow_nested() const; - _LIBCPP_HIDE_FROM_ABI exception_ptr nested_ptr() const _NOEXCEPT { return __ptr_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI exception_ptr nested_ptr() const _NOEXCEPT { return __ptr_; } }; template <class _Tp> diff --git a/libcxx/include/__exception/operations.h b/libcxx/include/__exception/operations.h index 29d5c69..2b93ad2 100644 --- a/libcxx/include/__exception/operations.h +++ b/libcxx/include/__exception/operations.h @@ -20,22 +20,22 @@ _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD defined(_LIBCPP_BUILDING_LIBRARY) using unexpected_handler = void (*)(); _LIBCPP_EXPORTED_FROM_ABI unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT; -_LIBCPP_EXPORTED_FROM_ABI unexpected_handler get_unexpected() _NOEXCEPT; +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unexpected_handler get_unexpected() _NOEXCEPT; [[__noreturn__]] _LIBCPP_EXPORTED_FROM_ABI void unexpected(); #endif using terminate_handler = void (*)(); _LIBCPP_EXPORTED_FROM_ABI terminate_handler set_terminate(terminate_handler) _NOEXCEPT; -_LIBCPP_EXPORTED_FROM_ABI terminate_handler get_terminate() _NOEXCEPT; +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI terminate_handler get_terminate() _NOEXCEPT; #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION) -_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 bool uncaught_exception() _NOEXCEPT; +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 bool uncaught_exception() _NOEXCEPT; #endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION) -_LIBCPP_EXPORTED_FROM_ABI int uncaught_exceptions() _NOEXCEPT; +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI int uncaught_exceptions() _NOEXCEPT; class _LIBCPP_EXPORTED_FROM_ABI exception_ptr; -_LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT; +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT; [[__noreturn__]] _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr); _LIBCPP_END_UNVERSIONED_NAMESPACE_STD diff --git a/libcxx/include/__expected/expected.h b/libcxx/include/__expected/expected.h index 8b3eeeb..be37e8a 100644 --- a/libcxx/include/__expected/expected.h +++ b/libcxx/include/__expected/expected.h @@ -30,7 +30,6 @@ #include <__type_traits/is_nothrow_assignable.h> #include <__type_traits/is_nothrow_constructible.h> #include <__type_traits/is_reference.h> -#include <__type_traits/is_replaceable.h> #include <__type_traits/is_same.h> #include <__type_traits/is_swappable.h> #include <__type_traits/is_trivially_constructible.h> @@ -472,8 +471,6 @@ public: __conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value && __libcpp_is_trivially_relocatable<_Err>::value, expected, void>; - using __replaceable _LIBCPP_NODEBUG = - __conditional_t<__is_replaceable_v<_Tp> && __is_replaceable_v<_Err>, expected, void>; template <class _Up> using rebind = expected<_Up, error_type>; diff --git a/libcxx/include/__filesystem/path.h b/libcxx/include/__filesystem/path.h index b3f3243..990ab6f 100644 --- a/libcxx/include/__filesystem/path.h +++ b/libcxx/include/__filesystem/path.h @@ -324,6 +324,7 @@ struct _PathCVT<char> { } }; +# if _LIBCPP_HAS_LOCALIZATION template <class _ECharT> struct _PathExport { typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower; @@ -364,7 +365,7 @@ struct _PathExport<char16_t> { } }; -# if _LIBCPP_HAS_CHAR8_T +# if _LIBCPP_HAS_CHAR8_T template <> struct _PathExport<char8_t> { typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower; @@ -374,8 +375,9 @@ struct _PathExport<char8_t> { _Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size()); } }; -# endif // _LIBCPP_HAS_CHAR8_T -# endif /* _LIBCPP_WIN32API */ +# endif // _LIBCPP_HAS_CHAR8_T +# endif // _LIBCPP_HAS_LOCALIZATION +# endif // _LIBCPP_WIN32API class _LIBCPP_EXPORTED_FROM_ABI path { template <class _SourceOrIter, class _Tp = path&> diff --git a/libcxx/include/__filesystem/u8path.h b/libcxx/include/__filesystem/u8path.h index 885372b..ebdd51b 100644 --- a/libcxx/include/__filesystem/u8path.h +++ b/libcxx/include/__filesystem/u8path.h @@ -24,28 +24,30 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM +# if !defined(_LIBCPP_WIN32API) || _LIBCPP_HAS_LOCALIZATION template <class _InputIt, __enable_if_t<__is_pathable<_InputIt>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _InputIt __l) { static_assert( -# if _LIBCPP_HAS_CHAR8_T +# if _LIBCPP_HAS_CHAR8_T is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value || -# endif +# endif is_same<typename __is_pathable<_InputIt>::__char_type, char>::value, "u8path(Iter, Iter) requires Iter have a value_type of type 'char'" " or 'char8_t'"); -# if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) string __tmp(__f, __l); using _CVT = __widen_from_utf8<sizeof(wchar_t) * __CHAR_BIT__>; std::wstring __w; __w.reserve(__tmp.size()); _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); return path(__w); -# else +# else return path(__f, __l); -# endif /* !_LIBCPP_WIN32API */ +# endif // defined(_LIBCPP_WIN32API) } +# endif // !defined(_LIBCPP_WIN32API) || _LIBCPP_HAS_LOCALIZATION -# if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) && _LIBCPP_HAS_LOCALIZATION template <class _InputIt, __enable_if_t<__is_pathable<_InputIt>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _NullSentinel) { static_assert( @@ -65,7 +67,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); return path(__w); } -# endif /* _LIBCPP_WIN32API */ +# endif // defined(_LIBCPP_WIN32API) && _LIBCPP_HAS_LOCALIZATION template <class _Source, __enable_if_t<__is_pathable<_Source>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(const _Source& __s) { diff --git a/libcxx/include/__flat_map/flat_map.h b/libcxx/include/__flat_map/flat_map.h index 159e652..84b60cd 100644 --- a/libcxx/include/__flat_map/flat_map.h +++ b/libcxx/include/__flat_map/flat_map.h @@ -409,41 +409,45 @@ public: } // iterators - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept { return iterator(__containers_.keys.begin(), __containers_.values.begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept { return const_iterator(__containers_.keys.begin(), __containers_.values.begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept { return iterator(__containers_.keys.end(), __containers_.values.end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept { return const_iterator(__containers_.keys.end(), __containers_.values.end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept { return reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept { return begin(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept { return end(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept { + return begin(); + } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept { + return end(); + } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } @@ -452,22 +456,22 @@ public: return __containers_.keys.empty(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept { return __containers_.keys.size(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept { return std::min<size_type>(__containers_.keys.max_size(), __containers_.values.max_size()); } // [flat.map.access], element access - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](const key_type& __x) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](const key_type& __x) requires is_constructible_v<mapped_type> { return try_emplace(__x).first->second; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](key_type&& __x) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](key_type&& __x) requires is_constructible_v<mapped_type> { return try_emplace(std::move(__x)).first->second; @@ -476,11 +480,11 @@ public: template <class _Kp> requires(__is_compare_transparent && is_constructible_v<key_type, _Kp> && is_constructible_v<mapped_type> && !is_convertible_v<_Kp &&, const_iterator> && !is_convertible_v<_Kp &&, iterator>) - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](_Kp&& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](_Kp&& __x) { return try_emplace(std::forward<_Kp>(__x)).first->second; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const key_type& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const key_type& __x) { auto __it = find(__x); if (__it == end()) { std::__throw_out_of_range("flat_map::at(const key_type&): Key does not exist"); @@ -488,7 +492,7 @@ public: return __it->second; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const key_type& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const key_type& __x) const { auto __it = find(__x); if (__it == end()) { std::__throw_out_of_range("flat_map::at(const key_type&) const: Key does not exist"); @@ -498,7 +502,7 @@ public: template <class _Kp> requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const _Kp& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const _Kp& __x) { auto __it = find(__x); if (__it == end()) { std::__throw_out_of_range("flat_map::at(const K&): Key does not exist"); @@ -508,7 +512,7 @@ public: template <class _Kp> requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const _Kp& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const _Kp& __x) const { auto __it = find(__x); if (__it == end()) { std::__throw_out_of_range("flat_map::at(const K&) const: Key does not exist"); @@ -596,7 +600,7 @@ public: insert(sorted_unique, __il.begin(), __il.end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 containers extract() && { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 containers extract() && { auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; }); auto __ret = std::move(__containers_); return __ret; @@ -753,116 +757,121 @@ public: } // observers - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const { return value_compare(__compare_); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const key_container_type& keys() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const key_container_type& keys() const noexcept { return __containers_.keys; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_container_type& values() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_container_type& + values() const noexcept { return __containers_.values; } // map operations - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) { return __find_impl(*this, __x); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const { return __find_impl(*this, __x); } template <class _Kp> requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) { return __find_impl(*this, __x); } template <class _Kp> requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const { return __find_impl(*this, __x); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const { return contains(__x) ? 1 : 0; } template <class _Kp> requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const { return contains(__x) ? 1 : 0; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const { return find(__x) != end(); } template <class _Kp> requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const { return find(__x) != end(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) { return __lower_bound<iterator>(*this, __x); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const key_type& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator + lower_bound(const key_type& __x) const { return __lower_bound<const_iterator>(*this, __x); } template <class _Kp> requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) { return __lower_bound<iterator>(*this, __x); } template <class _Kp> requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const { return __lower_bound<const_iterator>(*this, __x); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) { return __upper_bound<iterator>(*this, __x); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const key_type& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator + upper_bound(const key_type& __x) const { return __upper_bound<const_iterator>(*this, __x); } template <class _Kp> requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) { return __upper_bound<iterator>(*this, __x); } template <class _Kp> requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const { return __upper_bound<const_iterator>(*this, __x); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const key_type& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> + equal_range(const key_type& __x) { return __equal_range_impl(*this, __x); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator> equal_range(const key_type& __x) const { return __equal_range_impl(*this, __x); } template <class _Kp> requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const _Kp& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> + equal_range(const _Kp& __x) { return __equal_range_impl(*this, __x); } template <class _Kp> requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator> equal_range(const _Kp& __x) const { return __equal_range_impl(*this, __x); } diff --git a/libcxx/include/__flat_map/utils.h b/libcxx/include/__flat_map/utils.h index 3a05c71..4b07e38 100644 --- a/libcxx/include/__flat_map/utils.h +++ b/libcxx/include/__flat_map/utils.h @@ -16,6 +16,7 @@ #include <__utility/exception_guard.h> #include <__utility/forward.h> #include <__utility/move.h> +#include <__vector/container_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header diff --git a/libcxx/include/__flat_set/flat_set.h b/libcxx/include/__flat_set/flat_set.h index 0c8fdb5..1be38f1 100644 --- a/libcxx/include/__flat_set/flat_set.h +++ b/libcxx/include/__flat_set/flat_set.h @@ -339,38 +339,42 @@ public: } // iterators - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept { return iterator(std::as_const(__keys_).begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept { return const_iterator(__keys_.begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept { return iterator(std::as_const(__keys_).end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept { return const_iterator(__keys_.end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept { return reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept { return begin(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept { return end(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept { + return begin(); + } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept { + return end(); + } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } @@ -379,9 +383,13 @@ public: return __keys_.empty(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept { return __keys_.size(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept { + return __keys_.size(); + } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept { return __keys_.max_size(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept { + return __keys_.max_size(); + } // [flat.set.modifiers], modifiers template <class... _Args> @@ -466,7 +474,7 @@ public: insert(sorted_unique, __il.begin(), __il.end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 container_type extract() && { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 container_type extract() && { auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; }); auto __ret = std::move(__keys_); return __ret; @@ -528,111 +536,117 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() noexcept { __keys_.clear(); } // observers - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const { return __compare_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const { + return __compare_; + } // set operations - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) { return __find_impl(*this, __x); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const { return __find_impl(*this, __x); } template <class _Kp> requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) { return __find_impl(*this, __x); } template <class _Kp> requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const { return __find_impl(*this, __x); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const { return contains(__x) ? 1 : 0; } template <class _Kp> requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const { return contains(__x) ? 1 : 0; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const { return find(__x) != end(); } template <class _Kp> requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const { return find(__x) != end(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) { const auto& __keys = __keys_; return iterator(std::lower_bound(__keys.begin(), __keys.end(), __x, __compare_)); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const key_type& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator + lower_bound(const key_type& __x) const { return const_iterator(std::lower_bound(__keys_.begin(), __keys_.end(), __x, __compare_)); } template <class _Kp> requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) { const auto& __keys = __keys_; return iterator(std::lower_bound(__keys.begin(), __keys.end(), __x, __compare_)); } template <class _Kp> requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const { return const_iterator(std::lower_bound(__keys_.begin(), __keys_.end(), __x, __compare_)); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) { const auto& __keys = __keys_; return iterator(std::upper_bound(__keys.begin(), __keys.end(), __x, __compare_)); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const key_type& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator + upper_bound(const key_type& __x) const { return const_iterator(std::upper_bound(__keys_.begin(), __keys_.end(), __x, __compare_)); } template <class _Kp> requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) { const auto& __keys = __keys_; return iterator(std::upper_bound(__keys.begin(), __keys.end(), __x, __compare_)); } template <class _Kp> requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const { return const_iterator(std::upper_bound(__keys_.begin(), __keys_.end(), __x, __compare_)); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const key_type& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> + equal_range(const key_type& __x) { return __equal_range_impl(*this, __x); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator> equal_range(const key_type& __x) const { return __equal_range_impl(*this, __x); } template <class _Kp> requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const _Kp& __x) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> + equal_range(const _Kp& __x) { return __equal_range_impl(*this, __x); } template <class _Kp> requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator> equal_range(const _Kp& __x) const { return __equal_range_impl(*this, __x); } diff --git a/libcxx/include/__functional/bind.h b/libcxx/include/__functional/bind.h index def9e4c..cbe8660 100644 --- a/libcxx/include/__functional/bind.h +++ b/libcxx/include/__functional/bind.h @@ -81,16 +81,12 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& __mu(reference_w return __t.get(); } -template <class _Ti, class... _Uj, size_t... _Indx> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t<_Ti&, _Uj...> -__mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __index_sequence<_Indx...>) { - return __ti(std::forward<_Uj>(std::get<_Indx>(__uj))...); -} - template <class _Ti, class... _Uj, __enable_if_t<is_bind_expression<_Ti>::value, int> = 0> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t<_Ti&, _Uj...> __mu(_Ti& __ti, tuple<_Uj...>& __uj) { - return std::__mu_expand(__ti, __uj, __make_index_sequence<sizeof...(_Uj)>()); + return [&]<size_t... _Indices>(__index_sequence<_Indices...>) -> __invoke_result_t<_Ti&, _Uj...> { + return __ti(std::forward<_Uj>(std::get<_Indices>(__uj))...); + }(__index_sequence_for<_Uj...>{}); } template <bool _IsPh, class _Ti, class _Uj> @@ -217,10 +213,7 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type operator()(_Args&&... __args) { return std::__apply_functor( - __f_, - __bound_args_, - __make_index_sequence<sizeof...(_BoundArgs)>(), - tuple<_Args&&...>(std::forward<_Args>(__args)...)); + __f_, __bound_args_, __index_sequence_for<_BoundArgs...>(), tuple<_Args&&...>(std::forward<_Args>(__args)...)); } template <class... _Args> @@ -228,10 +221,7 @@ public: typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type operator()(_Args&&... __args) const { return std::__apply_functor( - __f_, - __bound_args_, - __make_index_sequence<sizeof...(_BoundArgs)>(), - tuple<_Args&&...>(std::forward<_Args>(__args)...)); + __f_, __bound_args_, __index_sequence_for<_BoundArgs...>(), tuple<_Args&&...>(std::forward<_Args>(__args)...)); } }; @@ -278,14 +268,14 @@ template <class _Rp, class _Fp, class... _BoundArgs> struct is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {}; template <class _Fp, class... _BoundArgs> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind<_Fp, _BoundArgs...> +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind<_Fp, _BoundArgs...> bind(_Fp&& __f, _BoundArgs&&... __bound_args) { typedef __bind<_Fp, _BoundArgs...> type; return type(std::forward<_Fp>(__f), std::forward<_BoundArgs>(__bound_args)...); } template <class _Rp, class _Fp, class... _BoundArgs> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind_r<_Rp, _Fp, _BoundArgs...> +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind_r<_Rp, _Fp, _BoundArgs...> bind(_Fp&& __f, _BoundArgs&&... __bound_args) { typedef __bind_r<_Rp, _Fp, _BoundArgs...> type; return type(std::forward<_Fp>(__f), std::forward<_BoundArgs>(__bound_args)...); diff --git a/libcxx/include/__functional/bind_back.h b/libcxx/include/__functional/bind_back.h index e44768d..4117714 100644 --- a/libcxx/include/__functional/bind_back.h +++ b/libcxx/include/__functional/bind_back.h @@ -64,7 +64,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __bind_back(_Fn&& __f, _Args&&... __args) n # if _LIBCPP_STD_VER >= 23 template <class _Fn, class... _Args> -_LIBCPP_HIDE_FROM_ABI constexpr auto bind_back(_Fn&& __f, _Args&&... __args) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto bind_back(_Fn&& __f, _Args&&... __args) { static_assert(is_constructible_v<decay_t<_Fn>, _Fn>, "bind_back requires decay_t<F> to be constructible from F"); static_assert(is_move_constructible_v<decay_t<_Fn>>, "bind_back requires decay_t<F> to be move constructible"); static_assert((is_constructible_v<decay_t<_Args>, _Args> && ...), diff --git a/libcxx/include/__functional/bind_front.h b/libcxx/include/__functional/bind_front.h index 87ef3af..427accf 100644 --- a/libcxx/include/__functional/bind_front.h +++ b/libcxx/include/__functional/bind_front.h @@ -43,7 +43,7 @@ struct __bind_front_t : __perfect_forward<__bind_front_op, _Fn, _BoundArgs...> { template <class _Fn, class... _Args> requires is_constructible_v<decay_t<_Fn>, _Fn> && is_move_constructible_v<decay_t<_Fn>> && (is_constructible_v<decay_t<_Args>, _Args> && ...) && (is_move_constructible_v<decay_t<_Args>> && ...) -_LIBCPP_HIDE_FROM_ABI constexpr auto bind_front(_Fn&& __f, _Args&&... __args) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto bind_front(_Fn&& __f, _Args&&... __args) { return __bind_front_t<decay_t<_Fn>, decay_t<_Args>...>(std::forward<_Fn>(__f), std::forward<_Args>(__args)...); } diff --git a/libcxx/include/__functional/function.h b/libcxx/include/__functional/function.h index c768fd9..121417f 100644 --- a/libcxx/include/__functional/function.h +++ b/libcxx/include/__functional/function.h @@ -672,11 +672,11 @@ public: # if _LIBCPP_HAS_RTTI // function target access: - _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT; template <typename _Tp> - _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT; template <typename _Tp> - _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT; # endif // _LIBCPP_HAS_RTTI }; diff --git a/libcxx/include/__functional/hash.h b/libcxx/include/__functional/hash.h index f74f25f..d81ff1a 100644 --- a/libcxx/include/__functional/hash.h +++ b/libcxx/include/__functional/hash.h @@ -435,7 +435,7 @@ struct hash : public __hash_impl<_Tp> {}; template <> struct hash<nullptr_t> : public __unary_function<nullptr_t, size_t> { - _LIBCPP_HIDE_FROM_ABI size_t operator()(nullptr_t) const _NOEXCEPT { return 662607004ull; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(nullptr_t) const _NOEXCEPT { return 662607004ull; } }; #ifndef _LIBCPP_CXX03_LANG diff --git a/libcxx/include/__functional/mem_fn.h b/libcxx/include/__functional/mem_fn.h index 6903939..1c9340c 100644 --- a/libcxx/include/__functional/mem_fn.h +++ b/libcxx/include/__functional/mem_fn.h @@ -43,7 +43,8 @@ public: }; template <class _Rp, class _Tp> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __mem_fn<_Rp _Tp::*> mem_fn(_Rp _Tp::*__pm) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __mem_fn<_Rp _Tp::*> +mem_fn(_Rp _Tp::* __pm) _NOEXCEPT { return __mem_fn<_Rp _Tp::*>(__pm); } diff --git a/libcxx/include/__functional/reference_wrapper.h b/libcxx/include/__functional/reference_wrapper.h index 148703b..b1efd9f 100644 --- a/libcxx/include/__functional/reference_wrapper.h +++ b/libcxx/include/__functional/reference_wrapper.h @@ -58,7 +58,7 @@ public: // access _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator type&() const _NOEXCEPT { return *__f_; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 type& get() const _NOEXCEPT { return *__f_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 type& get() const _NOEXCEPT { return *__f_; } // invoke template <class... _ArgTypes> @@ -128,23 +128,25 @@ reference_wrapper(_Tp&) -> reference_wrapper<_Tp>; #endif template <class _Tp> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(_Tp& __t) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(_Tp& __t) _NOEXCEPT { return reference_wrapper<_Tp>(__t); } template <class _Tp> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(reference_wrapper<_Tp> __t) _NOEXCEPT { return __t; } template <class _Tp> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp> cref(const _Tp& __t) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp> +cref(const _Tp& __t) _NOEXCEPT { return reference_wrapper<const _Tp>(__t); } template <class _Tp> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp> +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp> cref(reference_wrapper<_Tp> __t) _NOEXCEPT { return __t; } diff --git a/libcxx/include/__functional/weak_result_type.h b/libcxx/include/__functional/weak_result_type.h index aa462e4..4232bdc 100644 --- a/libcxx/include/__functional/weak_result_type.h +++ b/libcxx/include/__functional/weak_result_type.h @@ -13,9 +13,9 @@ #include <__config> #include <__functional/binary_function.h> #include <__functional/unary_function.h> -#include <__type_traits/integral_constant.h> #include <__type_traits/invoke.h> #include <__type_traits/is_same.h> +#include <__type_traits/void_t.h> #include <__utility/declval.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -24,50 +24,36 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Tp> -struct __has_result_type { -private: - template <class _Up> - static false_type __test(...); - template <class _Up> - static true_type __test(typename _Up::result_type* = 0); +template <class _Tp, class = void> +inline const bool __has_result_type_v = false; -public: - static const bool value = decltype(__test<_Tp>(0))::value; -}; +template <class _Tp> +inline const bool __has_result_type_v<_Tp, __void_t<typename _Tp::result_type*> > = true; // __weak_result_type template <class _Tp> struct __derives_from_unary_function { private: - struct __two { - char __lx; - char __lxx; - }; - static __two __test(...); + static void __find_base(...); template <class _Ap, class _Rp> - static __unary_function<_Ap, _Rp> __test(const volatile __unary_function<_Ap, _Rp>*); + static __unary_function<_Ap, _Rp> __find_base(const volatile __unary_function<_Ap, _Rp>*); public: - static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value; - typedef decltype(__test((_Tp*)0)) type; + using type = decltype(__find_base(static_cast<_Tp*>(nullptr))); + static const bool value = !is_same<type, void>::value; }; template <class _Tp> struct __derives_from_binary_function { private: - struct __two { - char __lx; - char __lxx; - }; - static __two __test(...); + static void __find_base(...); template <class _A1, class _A2, class _Rp> - static __binary_function<_A1, _A2, _Rp> __test(const volatile __binary_function<_A1, _A2, _Rp>*); + static __binary_function<_A1, _A2, _Rp> __find_base(const volatile __binary_function<_A1, _A2, _Rp>*); public: - static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value; - typedef decltype(__test((_Tp*)0)) type; + using type = decltype(__find_base(static_cast<_Tp*>(nullptr))); + static const bool value = !is_same<type, void>::value; }; template <class _Tp, bool = __derives_from_unary_function<_Tp>::value> @@ -85,7 +71,7 @@ struct __maybe_derive_from_binary_function // bool is true template <class _Tp> struct __maybe_derive_from_binary_function<_Tp, false> {}; -template <class _Tp, bool = __has_result_type<_Tp>::value> +template <class _Tp, bool = __has_result_type_v<_Tp> > struct __weak_result_type_imp // bool is true : public __maybe_derive_from_unary_function<_Tp>, public __maybe_derive_from_binary_function<_Tp> { diff --git a/libcxx/include/__fwd/ios.h b/libcxx/include/__fwd/ios.h index 831624f..fd6738a 100644 --- a/libcxx/include/__fwd/ios.h +++ b/libcxx/include/__fwd/ios.h @@ -31,7 +31,7 @@ using wios = basic_ios<wchar_t>; template <class _CharT, class _Traits> class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wios)) basic_ios; -#if defined(_NEWLIB_VERSION) +#if _LIBCPP_LIBC_NEWLIB // On newlib, off_t is 'long int' using streamoff = long int; // for char_traits in <string> #else diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table index e189794..ef487fb 100644 --- a/libcxx/include/__hash_table +++ b/libcxx/include/__hash_table @@ -1910,6 +1910,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, const_it __bucket_list_[__next_chash] = __before_first; __chash = __next_chash; } + } else { // When __next is a nullptr we've fully erased the last bucket. Update the bucket list accordingly. + __bucket_list_[__chash] = nullptr; } } diff --git a/libcxx/include/__iterator/wrap_iter.h b/libcxx/include/__iterator/wrap_iter.h index d18d968..98745f6 100644 --- a/libcxx/include/__iterator/wrap_iter.h +++ b/libcxx/include/__iterator/wrap_iter.h @@ -117,8 +117,8 @@ private: friend class span; template <class _Tp, size_t _Size> friend struct array; - template <class _Tp> - friend class optional; + template <class _Tp, class> + friend struct __optional_iterator; }; template <class _Iter1> diff --git a/libcxx/include/__locale b/libcxx/include/__locale index eb7b778..c2602af 100644 --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -57,9 +57,8 @@ _LIBCPP_HIDE_FROM_ABI const _Facet& use_facet(const locale&); class _LIBCPP_EXPORTED_FROM_ABI locale { public: // locale is essentially a shared_ptr that doesn't support weak_ptrs and never got a move constructor, - // so it is trivially relocatable. Like shared_ptr, it is also replaceable. + // so it is trivially relocatable. using __trivially_relocatable _LIBCPP_NODEBUG = locale; - using __replaceable _LIBCPP_NODEBUG = locale; // types: class _LIBCPP_EXPORTED_FROM_ABI facet; @@ -389,7 +388,7 @@ public: static const mask xdigit = _ISXDIGIT; static const mask blank = _ISBLANK; static const mask __regex_word = 0x8000; -# elif defined(_NEWLIB_VERSION) +# elif _LIBCPP_LIBC_NEWLIB // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h. typedef char mask; // In case char is signed, static_cast is needed to avoid warning on diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h index 8c8f000..a5849df 100644 --- a/libcxx/include/__locale_dir/locale_base_api.h +++ b/libcxx/include/__locale_dir/locale_base_api.h @@ -57,15 +57,11 @@ // float __strtof(const char*, char**, __locale_t); // double __strtod(const char*, char**, __locale_t); // long double __strtold(const char*, char**, __locale_t); -// long long __strtoll(const char*, char**, __locale_t); -// unsigned long long __strtoull(const char*, char**, __locale_t); // } // // Character manipulation functions // -------------------------------- // namespace __locale { -// int __isdigit(int, __locale_t); // required by the headers -// int __isxdigit(int, __locale_t); // required by the headers // int __toupper(int, __locale_t); // int __tolower(int, __locale_t); // int __strcoll(const char*, const char*, __locale_t); @@ -106,7 +102,6 @@ // // int __snprintf(char*, size_t, __locale_t, const char*, ...); // required by the headers // int __asprintf(char**, __locale_t, const char*, ...); // required by the headers -// int __sscanf(const char*, __locale_t, const char*, ...); // required by the headers // } #if _LIBCPP_HAS_LOCALIZATION @@ -123,6 +118,8 @@ # include <__locale_dir/support/fuchsia.h> # elif defined(__linux__) # include <__locale_dir/support/linux.h> +# elif _LIBCPP_LIBC_NEWLIB +# include <__locale_dir/support/newlib.h> # else // TODO: This is a temporary definition to bridge between the old way we defined the locale base API @@ -133,8 +130,6 @@ # include <__locale_dir/locale_base_api/ibm.h> # elif defined(__OpenBSD__) # include <__locale_dir/locale_base_api/openbsd.h> -# elif defined(__wasi__) || _LIBCPP_HAS_MUSL_LIBC -# include <__locale_dir/locale_base_api/musl.h> # endif # include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h> @@ -194,21 +189,9 @@ inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __ return strtold_l(__nptr, __endptr, __loc); } -inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) { - return strtoll_l(__nptr, __endptr, __base, __loc); -} - -inline _LIBCPP_HIDE_FROM_ABI unsigned long long -__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) { - return strtoull_l(__nptr, __endptr, __base, __loc); -} - // // Character manipulation functions // -inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __ch, __locale_t __loc) { return isdigit_l(__ch, __loc); } -inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __ch, __locale_t __loc) { return isxdigit_l(__ch, __loc); } - # if defined(_LIBCPP_BUILDING_LIBRARY) inline _LIBCPP_HIDE_FROM_ABI int __strcoll(const char* __s1, const char* __s2, __locale_t __loc) { return strcoll_l(__s1, __s2, __loc); @@ -304,11 +287,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __ char** __s, __locale_t __loc, const char* __format, _Args&&... __args) { return std::__libcpp_asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...); } -template <class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf( - const char* __s, __locale_t __loc, const char* __format, _Args&&... __args) { - return std::__libcpp_sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...); -} _LIBCPP_DIAGNOSTIC_POP # undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT diff --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h index b62a1b7..8cdbe0c 100644 --- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h +++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h @@ -125,16 +125,6 @@ inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __libcpp_asprintf_l( return __res; } -inline _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __libcpp_sscanf_l( - const char* __s, locale_t __l, const char* __format, ...) { - va_list __va; - va_start(__va, __format); - __locale_guard __current(__l); - int __res = vsscanf(__s, __format, __va); - va_end(__va); - return __res; -} - _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H diff --git a/libcxx/include/__locale_dir/locale_base_api/ibm.h b/libcxx/include/__locale_dir/locale_base_api/ibm.h index 1d1d15d..47a83ea 100644 --- a/libcxx/include/__locale_dir/locale_base_api/ibm.h +++ b/libcxx/include/__locale_dir/locale_base_api/ibm.h @@ -53,11 +53,6 @@ private: // The following are not POSIX routines. These are quick-and-dirty hacks // to make things pretend to work -inline _LIBCPP_HIDE_FROM_ABI long long strtoll_l(const char* __nptr, char** __endptr, int __base, locale_t locale) { - __setAndRestore __newloc(locale); - return ::strtoll(__nptr, __endptr, __base); -} - inline _LIBCPP_HIDE_FROM_ABI double strtod_l(const char* __nptr, char** __endptr, locale_t locale) { __setAndRestore __newloc(locale); return ::strtod(__nptr, __endptr); @@ -73,12 +68,6 @@ inline _LIBCPP_HIDE_FROM_ABI long double strtold_l(const char* __nptr, char** __ return ::strtold(__nptr, __endptr); } -inline _LIBCPP_HIDE_FROM_ABI unsigned long long -strtoull_l(const char* __nptr, char** __endptr, int __base, locale_t locale) { - __setAndRestore __newloc(locale); - return ::strtoull(__nptr, __endptr, __base); -} - inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 2, 0) int vasprintf(char** strp, const char* fmt, va_list ap) { const size_t buff_size = 256; diff --git a/libcxx/include/__locale_dir/locale_base_api/musl.h b/libcxx/include/__locale_dir/locale_base_api/musl.h deleted file mode 100644 index 1653214..0000000 --- a/libcxx/include/__locale_dir/locale_base_api/musl.h +++ /dev/null @@ -1,31 +0,0 @@ -// -*- C++ -*- -//===-----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// This adds support for the extended locale functions that are currently -// missing from the Musl C library. -// -// This only works when the specified locale is "C" or "POSIX", but that's -// about as good as we can do without implementing full xlocale support -// in Musl. -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_MUSL_H -#define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_MUSL_H - -#include <cstdlib> -#include <cwchar> - -inline _LIBCPP_HIDE_FROM_ABI long long strtoll_l(const char* __nptr, char** __endptr, int __base, locale_t) { - return ::strtoll(__nptr, __endptr, __base); -} - -inline _LIBCPP_HIDE_FROM_ABI unsigned long long strtoull_l(const char* __nptr, char** __endptr, int __base, locale_t) { - return ::strtoull(__nptr, __endptr, __base); -} - -#endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_MUSL_H diff --git a/libcxx/include/__locale_dir/messages.h b/libcxx/include/__locale_dir/messages.h index c04bf04..686f472 100644 --- a/libcxx/include/__locale_dir/messages.h +++ b/libcxx/include/__locale_dir/messages.h @@ -22,7 +22,7 @@ # if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) // Most unix variants have catopen. These are the specific ones that don't. -# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__EMSCRIPTEN__) +# if !defined(__BIONIC__) && !_LIBCPP_LIBC_NEWLIB && !defined(__EMSCRIPTEN__) # define _LIBCPP_HAS_CATOPEN 1 # include <nl_types.h> # else diff --git a/libcxx/include/__locale_dir/num.h b/libcxx/include/__locale_dir/num.h index ff357cd..b7ea02e 100644 --- a/libcxx/include/__locale_dir/num.h +++ b/libcxx/include/__locale_dir/num.h @@ -12,6 +12,7 @@ #include <__algorithm/copy.h> #include <__algorithm/find.h> #include <__algorithm/reverse.h> +#include <__algorithm/simd_utils.h> #include <__charconv/to_chars_integral.h> #include <__charconv/traits.h> #include <__config> @@ -23,6 +24,7 @@ #include <__locale_dir/scan_keyword.h> #include <__memory/unique_ptr.h> #include <__system_error/errc.h> +#include <__type_traits/is_signed.h> #include <cerrno> #include <ios> #include <streambuf> @@ -47,9 +49,9 @@ struct _LIBCPP_EXPORTED_FROM_ABI __num_get_base { static int __get_base(ios_base&); static const char __src[33]; // "0123456789abcdefABCDEFxX+-pPiInN" // count of leading characters in __src used for parsing integers ("012..X+-") - static const size_t __int_chr_cnt = 26; + static inline const size_t __int_chr_cnt = 26; // count of leading characters in __src used for parsing floating-point values ("012..-pP") - static const size_t __fp_chr_cnt = 28; + static inline const size_t __fp_chr_cnt = 28; }; template <class _CharT> @@ -72,7 +74,8 @@ struct __num_get : protected __num_get_base { [[__deprecated__("This exists only for ABI compatibility")]] static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep); - static int __stage2_int_loop( + + [[__deprecated__("This exists only for ABI compatibility")]] static int __stage2_int_loop( _CharT __ct, int __base, char* __a, @@ -84,11 +87,24 @@ struct __num_get : protected __num_get_base { unsigned*& __g_end, _CharT* __atoms); - _LIBCPP_HIDE_FROM_ABI static string __stage2_int_prep(ios_base& __iob, _CharT& __thousands_sep) { - locale __loc = __iob.getloc(); - const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); - __thousands_sep = __np.thousands_sep(); - return __np.grouping(); + _LIBCPP_HIDE_FROM_ABI static ptrdiff_t __atoms_offset(const _CharT* __atoms, _CharT __val) { + // TODO: Remove the manual vectorization once https://llvm.org/PR168551 is resolved +# if _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS + if constexpr (is_same<_CharT, char>::value) { + // TODO(LLVM 24): This can be removed, since -Wpsabi doesn't warn on [[gnu::always_inline]] functions anymore. + _LIBCPP_DIAGNOSTIC_PUSH + _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wpsabi") + using __vec = __simd_vector<char, 32>; + __vec __chars = std::__broadcast<__vec>(__val); + __vec __cmp = std::__partial_load<__vec, __int_chr_cnt>(__atoms); + auto __res = __chars == __cmp; + if (std::__none_of(__res)) + return __int_chr_cnt; + return std::min(__int_chr_cnt, std::__find_first_set(__res)); + _LIBCPP_DIAGNOSTIC_POP + } +# endif + return std::find(__atoms, __atoms + __int_chr_cnt, __val) - __atoms; } _LIBCPP_HIDE_FROM_ABI const _CharT* __do_widen(ios_base& __iob, _CharT* __atoms) const { @@ -122,54 +138,6 @@ string __num_get<_CharT>::__stage2_float_prep( } template <class _CharT> -int __num_get<_CharT>::__stage2_int_loop( - _CharT __ct, - int __base, - char* __a, - char*& __a_end, - unsigned& __dc, - _CharT __thousands_sep, - const string& __grouping, - unsigned* __g, - unsigned*& __g_end, - _CharT* __atoms) { - if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25])) { - *__a_end++ = __ct == __atoms[24] ? '+' : '-'; - __dc = 0; - return 0; - } - if (__grouping.size() != 0 && __ct == __thousands_sep) { - if (__g_end - __g < __num_get_buf_sz) { - *__g_end++ = __dc; - __dc = 0; - } - return 0; - } - ptrdiff_t __f = std::find(__atoms, __atoms + __int_chr_cnt, __ct) - __atoms; - if (__f >= 24) - return -1; - switch (__base) { - case 8: - case 10: - if (__f >= __base) - return -1; - break; - case 16: - if (__f < 22) - break; - if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0') { - __dc = 0; - *__a_end++ = __src[__f]; - return 0; - } - return -1; - } - *__a_end++ = __src[__f]; - ++__dc; - return 0; -} - -template <class _CharT> int __num_get<_CharT>::__stage2_float_loop( _CharT __ct, bool& __in_units, @@ -273,65 +241,6 @@ _LIBCPP_HIDE_FROM_ABI _Tp __num_get_float(const char* __a, const char* __a_end, return 0; } -template <class _Tp> -_LIBCPP_HIDE_FROM_ABI _Tp -__num_get_signed_integral(const char* __a, const char* __a_end, ios_base::iostate& __err, int __base) { - if (__a != __a_end) { - __libcpp_remove_reference_t<decltype(errno)> __save_errno = errno; - errno = 0; - char* __p2; - long long __ll = __locale::__strtoll(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); - __libcpp_remove_reference_t<decltype(errno)> __current_errno = errno; - if (__current_errno == 0) - errno = __save_errno; - if (__p2 != __a_end) { - __err = ios_base::failbit; - return 0; - } else if (__current_errno == ERANGE || __ll < numeric_limits<_Tp>::min() || numeric_limits<_Tp>::max() < __ll) { - __err = ios_base::failbit; - if (__ll > 0) - return numeric_limits<_Tp>::max(); - else - return numeric_limits<_Tp>::min(); - } - return static_cast<_Tp>(__ll); - } - __err = ios_base::failbit; - return 0; -} - -template <class _Tp> -_LIBCPP_HIDE_FROM_ABI _Tp -__num_get_unsigned_integral(const char* __a, const char* __a_end, ios_base::iostate& __err, int __base) { - if (__a != __a_end) { - const bool __negate = *__a == '-'; - if (__negate && ++__a == __a_end) { - __err = ios_base::failbit; - return 0; - } - __libcpp_remove_reference_t<decltype(errno)> __save_errno = errno; - errno = 0; - char* __p2; - unsigned long long __ll = __locale::__strtoull(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); - __libcpp_remove_reference_t<decltype(errno)> __current_errno = errno; - if (__current_errno == 0) - errno = __save_errno; - if (__p2 != __a_end) { - __err = ios_base::failbit; - return 0; - } else if (__current_errno == ERANGE || numeric_limits<_Tp>::max() < __ll) { - __err = ios_base::failbit; - return numeric_limits<_Tp>::max(); - } - _Tp __res = static_cast<_Tp>(__ll); - if (__negate) - __res = -__res; - return __res; - } - __err = ios_base::failbit; - return 0; -} - template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > class num_get : public locale::facet, private __num_get<_CharT> { public: @@ -469,137 +378,196 @@ protected: return __b; } - template <class _Signed> - _LIBCPP_HIDE_FROM_ABI iter_type - __do_get_signed(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Signed& __v) const { + template <class _MaybeSigned> + iter_type __do_get_integral( + iter_type __first, iter_type __last, ios_base& __iob, ios_base::iostate& __err, _MaybeSigned& __v) const { + using _Unsigned = __make_unsigned_t<_MaybeSigned>; + // Stage 1 int __base = this->__get_base(__iob); - // Stage 2 - char_type __thousands_sep; - const int __atoms_size = __num_get_base::__int_chr_cnt; - char_type __atoms1[__atoms_size]; - const char_type* __atoms = this->__do_widen(__iob, __atoms1); - string __grouping = this->__stage2_int_prep(__iob, __thousands_sep); - string __buf; - __buf.resize(__buf.capacity()); - char* __a = &__buf[0]; - char* __a_end = __a; + + // Stages 2 & 3 + // These are combined into a single step where we parse the characters and calculate the value in one go instead of + // storing the relevant characters first (in an allocated buffer) and parse the characters after we extracted them. + // This makes the whole process significantly faster, since we avoid potential allocations and copies. + + const auto& __numpunct = use_facet<numpunct<_CharT> >(__iob.getloc()); + char_type __thousands_sep = __numpunct.thousands_sep(); + string __grouping = __numpunct.grouping(); + + char_type __atoms_buffer[__num_get_base::__int_chr_cnt]; + const char_type* __atoms = this->__do_widen(__iob, __atoms_buffer); unsigned __g[__num_get_base::__num_get_buf_sz]; unsigned* __g_end = __g; unsigned __dc = 0; - for (; __b != __e; ++__b) { - if (__a_end == __a + __buf.size()) { - size_t __tmp = __buf.size(); - __buf.resize(2 * __buf.size()); - __buf.resize(__buf.capacity()); - __a = &__buf[0]; - __a_end = __a + __tmp; + + if (__first == __last) { + __err |= ios_base::eofbit | ios_base::failbit; + __v = 0; + return __first; + } + + while (!__grouping.empty() && *__first == __thousands_sep) { + ++__first; + if (__g_end - __g < this->__num_get_buf_sz) + *__g_end++ = 0; + } + + bool __negate = false; + // __c == '+' || __c == '-' + if (auto __c = *__first; __c == __atoms[24] || __c == __atoms[25]) { + __negate = __c == __atoms[25]; + ++__first; + } + + if (__first == __last) { + __err |= ios_base::eofbit | ios_base::failbit; + __v = 0; + return __first; + } + + bool __parsed_num = false; + + // If we don't have a pre-set base, figure it out and swallow any prefix + if (__base == 0) { + auto __c = *__first; + // __c == '0' + if (__c == __atoms[0]) { + ++__first; + if (__first == __last) { + __err |= ios_base::eofbit; + __v = 0; + return __first; + } + // __c2 == 'x' || __c2 == 'X' + if (auto __c2 = *__first; __c2 == __atoms[22] || __c2 == __atoms[23]) { + __base = 16; + ++__first; + } else { + __base = 8; + __parsed_num = true; // We only swallowed '0', so we've started to parse a number + } + } else { + __base = 10; + } + + // If the base has been specified explicitly, try to swallow the appropriate prefix. We only need to do something + // special for hex, since decimal has no prefix and octal's prefix is '0', which doesn't change the value that + // we'll parse if we don't swallow it. + } else if (__base == 16) { + // Try to swallow '0x' + + // *__first == '0' + if (*__first == __atoms[0]) { + ++__first; + if (__first == __last) { + __err |= ios_base::eofbit; + __v = 0; + return __first; + } + // __c == 'x' || __c == 'X' + if (auto __c = *__first; __c == __atoms[22] || __c == __atoms[23]) + ++__first; + else + __parsed_num = true; // We only swallowed '0', so we've started to parse a number } - if (this->__stage2_int_loop( - *__b, - __base, - __a, - __a_end, - __dc, - __thousands_sep, - __grouping, - __g, - __g_end, - const_cast<char_type*>(__atoms))) - break; } - if (__grouping.size() != 0 && __g_end - __g < __num_get_base::__num_get_buf_sz) - *__g_end++ = __dc; - // Stage 3 - __v = std::__num_get_signed_integral<_Signed>(__a, __a_end, __err, __base); - // Digit grouping checked - __check_grouping(__grouping, __g, __g_end, __err); - // EOF checked - if (__b == __e) - __err |= ios_base::eofbit; - return __b; - } - template <class _Unsigned> - _LIBCPP_HIDE_FROM_ABI iter_type - __do_get_unsigned(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Unsigned& __v) const { - // Stage 1 - int __base = this->__get_base(__iob); - // Stage 2 - char_type __thousands_sep; - const int __atoms_size = __num_get_base::__int_chr_cnt; - char_type __atoms1[__atoms_size]; - const char_type* __atoms = this->__do_widen(__iob, __atoms1); - string __grouping = this->__stage2_int_prep(__iob, __thousands_sep); - string __buf; - __buf.resize(__buf.capacity()); - char* __a = &__buf[0]; - char* __a_end = __a; - unsigned __g[__num_get_base::__num_get_buf_sz]; - unsigned* __g_end = __g; - unsigned __dc = 0; - for (; __b != __e; ++__b) { - if (__a_end == __a + __buf.size()) { - size_t __tmp = __buf.size(); - __buf.resize(2 * __buf.size()); - __buf.resize(__buf.capacity()); - __a = &__buf[0]; - __a_end = __a + __tmp; + // Calculate the actual number + _Unsigned __val = 0; + bool __overflowed = false; + for (; __first != __last; ++__first) { + auto __c = *__first; + if (!__grouping.empty() && __c == __thousands_sep) { + if (__g_end - __g < this->__num_get_buf_sz) { + *__g_end++ = __dc; + __dc = 0; + } + continue; } - if (this->__stage2_int_loop( - *__b, - __base, - __a, - __a_end, - __dc, - __thousands_sep, - __grouping, - __g, - __g_end, - const_cast<char_type*>(__atoms))) + auto __offset = this->__atoms_offset(__atoms, __c); + if (__offset >= 22) // Not a valid integer character break; + + if (__base == 16 && __offset >= 16) + __offset -= 6; + if (__offset >= __base) + break; + // __val = (__val * __base) + __offset + __overflowed |= __builtin_mul_overflow(__val, __base, std::addressof(__val)) || + __builtin_add_overflow(__val, __offset, std::addressof(__val)); + __parsed_num = true; + ++__dc; + } + + if (!__parsed_num) { + __err |= ios_base::failbit; + __v = 0; + } else if (__overflowed) { + __err |= ios_base::failbit; + __v = is_signed<_MaybeSigned>::value && __negate + ? numeric_limits<_MaybeSigned>::min() + : numeric_limits<_MaybeSigned>::max(); + } else if (!__negate) { + if (__val > static_cast<_Unsigned>(numeric_limits<_MaybeSigned>::max())) { + __err |= ios_base::failbit; + __v = numeric_limits<_MaybeSigned>::max(); + } else { + __v = __val; + } + } else if (is_signed<_MaybeSigned>::value) { + if (__val > static_cast<_Unsigned>(numeric_limits<_MaybeSigned>::max()) + 1) { + __err |= ios_base::failbit; + __v = numeric_limits<_MaybeSigned>::min(); + } else if (__val == static_cast<_Unsigned>(numeric_limits<_MaybeSigned>::max()) + 1) { + __v = numeric_limits<_MaybeSigned>::min(); + } else { + __v = -__val; + } + } else { + __v = -__val; } + if (__grouping.size() != 0 && __g_end - __g < __num_get_base::__num_get_buf_sz) *__g_end++ = __dc; - // Stage 3 - __v = std::__num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base); + // Digit grouping checked __check_grouping(__grouping, __g, __g_end, __err); // EOF checked - if (__b == __e) + if (__first == __last) __err |= ios_base::eofbit; - return __b; + return __first; } virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, bool& __v) const; virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long& __v) const { - return this->__do_get_signed(__b, __e, __iob, __err, __v); + return this->__do_get_integral(__b, __e, __iob, __err, __v); } virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long long& __v) const { - return this->__do_get_signed(__b, __e, __iob, __err, __v); + return this->__do_get_integral(__b, __e, __iob, __err, __v); } virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned short& __v) const { - return this->__do_get_unsigned(__b, __e, __iob, __err, __v); + return this->__do_get_integral(__b, __e, __iob, __err, __v); } virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned int& __v) const { - return this->__do_get_unsigned(__b, __e, __iob, __err, __v); + return this->__do_get_integral(__b, __e, __iob, __err, __v); } virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned long& __v) const { - return this->__do_get_unsigned(__b, __e, __iob, __err, __v); + return this->__do_get_integral(__b, __e, __iob, __err, __v); } virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned long long& __v) const { - return this->__do_get_unsigned(__b, __e, __iob, __err, __v); + return this->__do_get_integral(__b, __e, __iob, __err, __v); } virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, float& __v) const { @@ -653,40 +621,13 @@ _InputIterator num_get<_CharT, _InputIterator>::do_get( template <class _CharT, class _InputIterator> _InputIterator num_get<_CharT, _InputIterator>::do_get( iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, void*& __v) const { - // Stage 1 - int __base = 16; - // Stage 2 - char_type __atoms[__num_get_base::__int_chr_cnt]; - char_type __thousands_sep = char_type(); - string __grouping; - std::use_facet<ctype<_CharT> >(__iob.getloc()) - .widen(__num_get_base::__src, __num_get_base::__src + __num_get_base::__int_chr_cnt, __atoms); - string __buf; - __buf.resize(__buf.capacity()); - char* __a = &__buf[0]; - char* __a_end = __a; - unsigned __g[__num_get_base::__num_get_buf_sz]; - unsigned* __g_end = __g; - unsigned __dc = 0; - for (; __b != __e; ++__b) { - if (__a_end == __a + __buf.size()) { - size_t __tmp = __buf.size(); - __buf.resize(2 * __buf.size()); - __buf.resize(__buf.capacity()); - __a = &__buf[0]; - __a_end = __a + __tmp; - } - if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, __thousands_sep, __grouping, __g, __g_end, __atoms)) - break; - } - // Stage 3 - __buf.resize(__a_end - __a); - if (__locale::__sscanf(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1) - __err = ios_base::failbit; - // EOF checked - if (__b == __e) - __err |= ios_base::eofbit; - return __b; + auto __flags = __iob.flags(); + __iob.flags((__flags & ~ios_base::basefield & ~ios_base::uppercase) | ios_base::hex); + uintptr_t __ptr; + auto __res = __do_get_integral(__b, __e, __iob, __err, __ptr); + __iob.flags(__flags); + __v = reinterpret_cast<void*>(__ptr); + return __res; } extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<char>; @@ -749,6 +690,13 @@ void __num_put<_CharT>::__widen_and_group_int( __op = __ob + (__np - __nb); } +_LIBCPP_HIDE_FROM_ABI inline bool __isdigit(char __c) { return __c >= '0' && __c <= '9'; } + +_LIBCPP_HIDE_FROM_ABI inline bool __isxdigit(char __c) { + auto __lower = __c | 0x20; + return std::__isdigit(__c) || (__lower >= 'a' && __lower <= 'f'); +} + template <class _CharT> void __num_put<_CharT>::__widen_and_group_float( char* __nb, char* __np, char* __ne, _CharT* __ob, _CharT*& __op, _CharT*& __oe, const locale& __loc) { @@ -764,11 +712,11 @@ void __num_put<_CharT>::__widen_and_group_float( *__oe++ = __ct.widen(*__nf++); *__oe++ = __ct.widen(*__nf++); for (__ns = __nf; __ns < __ne; ++__ns) - if (!__locale::__isxdigit(*__ns, _LIBCPP_GET_C_LOCALE)) + if (!std::__isxdigit(*__ns)) break; } else { for (__ns = __nf; __ns < __ne; ++__ns) - if (!__locale::__isdigit(*__ns, _LIBCPP_GET_C_LOCALE)) + if (!std::__isdigit(*__ns)) break; } if (__grouping.empty()) { diff --git a/libcxx/include/__locale_dir/support/bsd_like.h b/libcxx/include/__locale_dir/support/bsd_like.h index 9d4bdd1..6f533b4e 100644 --- a/libcxx/include/__locale_dir/support/bsd_like.h +++ b/libcxx/include/__locale_dir/support/bsd_like.h @@ -79,22 +79,9 @@ inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __ return ::strtold_l(__nptr, __endptr, __loc); } -inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) { - return ::strtoll_l(__nptr, __endptr, __base, __loc); -} - -inline _LIBCPP_HIDE_FROM_ABI unsigned long long -__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) { - return ::strtoull_l(__nptr, __endptr, __base, __loc); -} - // // Character manipulation functions // -inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t __loc) { return ::isdigit_l(__c, __loc); } - -inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t __loc) { return ::isxdigit_l(__c, __loc); } - #if defined(_LIBCPP_BUILDING_LIBRARY) inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return ::toupper_l(__c, __loc); } @@ -215,12 +202,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __ char** __s, __locale_t __loc, const char* __format, _Args&&... __args) { return ::asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...); // non-standard } - -template <class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf( - const char* __s, __locale_t __loc, const char* __format, _Args&&... __args) { - return ::sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...); -} _LIBCPP_DIAGNOSTIC_POP #undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT diff --git a/libcxx/include/__locale_dir/support/fuchsia.h b/libcxx/include/__locale_dir/support/fuchsia.h index 4b9e63f..528bfeb 100644 --- a/libcxx/include/__locale_dir/support/fuchsia.h +++ b/libcxx/include/__locale_dir/support/fuchsia.h @@ -141,13 +141,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __ __locale_guard __current(__loc); return ::asprintf(__s, __format, std::forward<_Args>(__args)...); // non-standard } -template <class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf( - const char* __s, __locale_t __loc, const char* __format, _Args&&... __args) { - __locale_guard __current(__loc); - return std::sscanf(__s, __format, std::forward<_Args>(__args)...); -} - _LIBCPP_DIAGNOSTIC_POP #undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT diff --git a/libcxx/include/__locale_dir/support/linux.h b/libcxx/include/__locale_dir/support/linux.h index 23bcf44..1a589be 100644 --- a/libcxx/include/__locale_dir/support/linux.h +++ b/libcxx/include/__locale_dir/support/linux.h @@ -94,32 +94,9 @@ inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __ return ::strtold_l(__nptr, __endptr, __loc); } -inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) { -#if !_LIBCPP_HAS_MUSL_LIBC - return ::strtoll_l(__nptr, __endptr, __base, __loc); -#else - (void)__loc; - return ::strtoll(__nptr, __endptr, __base); -#endif -} - -inline _LIBCPP_HIDE_FROM_ABI unsigned long long -__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) { -#if !_LIBCPP_HAS_MUSL_LIBC - return ::strtoull_l(__nptr, __endptr, __base, __loc); -#else - (void)__loc; - return ::strtoull(__nptr, __endptr, __base); -#endif -} - // // Character manipulation functions // -inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t __loc) { return isdigit_l(__c, __loc); } - -inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t __loc) { return isxdigit_l(__c, __loc); } - #if defined(_LIBCPP_BUILDING_LIBRARY) inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return toupper_l(__c, __loc); } @@ -261,20 +238,6 @@ inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf( va_end(__va); return __res; } - -#ifndef _LIBCPP_COMPILER_GCC // GCC complains that this can't be always_inline due to C-style varargs -_LIBCPP_HIDE_FROM_ABI -#endif -inline _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf( - const char* __s, __locale_t __loc, const char* __format, ...) { - va_list __va; - va_start(__va, __format); - __locale_guard __current(__loc); - int __res = std::vsscanf(__s, __format, __va); - va_end(__va); - return __res; -} - } // namespace __locale _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__locale_dir/support/newlib.h b/libcxx/include/__locale_dir/support/newlib.h new file mode 100644 index 0000000..05c8a44 --- /dev/null +++ b/libcxx/include/__locale_dir/support/newlib.h @@ -0,0 +1,243 @@ +//===-----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___LOCALE_DIR_SUPPORT_NEWLIB_H +#define _LIBCPP___LOCALE_DIR_SUPPORT_NEWLIB_H + +#include <__config> +#include <__cstddef/size_t.h> +#include <__std_mbstate_t.h> +#include <clocale> // std::lconv +#include <cstdio> +#include <cstdlib> +#include <ctype.h> +#include <stdarg.h> +#include <string.h> +#include <time.h> +#if _LIBCPP_HAS_WIDE_CHARACTERS +# include <cwchar> +# include <wctype.h> +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD +namespace __locale { + +struct __locale_guard { + _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t& __loc) : __old_loc_(::uselocale(__loc)) {} + + _LIBCPP_HIDE_FROM_ABI ~__locale_guard() { + if (__old_loc_) + ::uselocale(__old_loc_); + } + + locale_t __old_loc_; + + __locale_guard(__locale_guard const&) = delete; + __locale_guard& operator=(__locale_guard const&) = delete; +}; + +// +// Locale management +// +#define _LIBCPP_COLLATE_MASK LC_COLLATE_MASK +#define _LIBCPP_CTYPE_MASK LC_CTYPE_MASK +#define _LIBCPP_MONETARY_MASK LC_MONETARY_MASK +#define _LIBCPP_NUMERIC_MASK LC_NUMERIC_MASK +#define _LIBCPP_TIME_MASK LC_TIME_MASK +#define _LIBCPP_MESSAGES_MASK LC_MESSAGES_MASK +#define _LIBCPP_ALL_MASK LC_ALL_MASK +#define _LIBCPP_LC_ALL LC_ALL + +using __locale_t _LIBCPP_NODEBUG = ::locale_t; + +#if defined(_LIBCPP_BUILDING_LIBRARY) +using __lconv_t _LIBCPP_NODEBUG = std::lconv; + +inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __locale, __locale_t __base) { + return ::newlocale(__category_mask, __locale, __base); +} + +inline _LIBCPP_HIDE_FROM_ABI void __freelocale(__locale_t __loc) { ::freelocale(__loc); } + +inline _LIBCPP_HIDE_FROM_ABI char* __setlocale(int __category, char const* __locale) { + return ::setlocale(__category, __locale); +} + +inline _LIBCPP_HIDE_FROM_ABI __lconv_t* __localeconv(__locale_t& __loc) { + __locale_guard __current(__loc); + return std::localeconv(); +} +#endif // _LIBCPP_BUILDING_LIBRARY + +// +// Strtonum functions +// +inline _LIBCPP_HIDE_FROM_ABI float __strtof(const char* __nptr, char** __endptr, __locale_t __loc) { + return ::strtof_l(__nptr, __endptr, __loc); +} + +inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr, __locale_t __loc) { + return ::strtod_l(__nptr, __endptr, __loc); +} + +inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __endptr, __locale_t __loc) { + return ::strtold_l(__nptr, __endptr, __loc); +} + +// +// Character manipulation functions +// +#if defined(_LIBCPP_BUILDING_LIBRARY) +inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return toupper_l(__c, __loc); } + +inline _LIBCPP_HIDE_FROM_ABI int __tolower(int __c, __locale_t __loc) { return tolower_l(__c, __loc); } + +inline _LIBCPP_HIDE_FROM_ABI int __strcoll(const char* __s1, const char* __s2, __locale_t __loc) { + return strcoll_l(__s1, __s2, __loc); +} + +inline _LIBCPP_HIDE_FROM_ABI size_t __strxfrm(char* __dest, const char* __src, size_t __n, __locale_t __loc) { + return strxfrm_l(__dest, __src, __n, __loc); +} + +# if _LIBCPP_HAS_WIDE_CHARACTERS +inline _LIBCPP_HIDE_FROM_ABI int __iswctype(wint_t __c, wctype_t __type, __locale_t __loc) { + return iswctype_l(__c, __type, __loc); +} + +inline _LIBCPP_HIDE_FROM_ABI int __iswspace(wint_t __c, __locale_t __loc) { return iswspace_l(__c, __loc); } + +inline _LIBCPP_HIDE_FROM_ABI int __iswprint(wint_t __c, __locale_t __loc) { return iswprint_l(__c, __loc); } + +inline _LIBCPP_HIDE_FROM_ABI int __iswcntrl(wint_t __c, __locale_t __loc) { return iswcntrl_l(__c, __loc); } + +inline _LIBCPP_HIDE_FROM_ABI int __iswupper(wint_t __c, __locale_t __loc) { return iswupper_l(__c, __loc); } + +inline _LIBCPP_HIDE_FROM_ABI int __iswlower(wint_t __c, __locale_t __loc) { return iswlower_l(__c, __loc); } + +inline _LIBCPP_HIDE_FROM_ABI int __iswalpha(wint_t __c, __locale_t __loc) { return iswalpha_l(__c, __loc); } + +inline _LIBCPP_HIDE_FROM_ABI int __iswblank(wint_t __c, __locale_t __loc) { return iswblank_l(__c, __loc); } + +inline _LIBCPP_HIDE_FROM_ABI int __iswdigit(wint_t __c, __locale_t __loc) { return iswdigit_l(__c, __loc); } + +inline _LIBCPP_HIDE_FROM_ABI int __iswpunct(wint_t __c, __locale_t __loc) { return iswpunct_l(__c, __loc); } + +inline _LIBCPP_HIDE_FROM_ABI int __iswxdigit(wint_t __c, __locale_t __loc) { return iswxdigit_l(__c, __loc); } + +inline _LIBCPP_HIDE_FROM_ABI wint_t __towupper(wint_t __c, __locale_t __loc) { return towupper_l(__c, __loc); } + +inline _LIBCPP_HIDE_FROM_ABI wint_t __towlower(wint_t __c, __locale_t __loc) { return towlower_l(__c, __loc); } + +inline _LIBCPP_HIDE_FROM_ABI int __wcscoll(const wchar_t* __ws1, const wchar_t* __ws2, __locale_t __loc) { + return wcscoll_l(__ws1, __ws2, __loc); +} + +inline _LIBCPP_HIDE_FROM_ABI size_t __wcsxfrm(wchar_t* __dest, const wchar_t* __src, size_t __n, __locale_t __loc) { + return wcsxfrm_l(__dest, __src, __n, __loc); +} +# endif // _LIBCPP_HAS_WIDE_CHARACTERS + +inline _LIBCPP_HIDE_FROM_ABI +size_t __strftime(char* __s, size_t __max, const char* __format, const struct tm* __tm, __locale_t __loc) { + return strftime_l(__s, __max, __format, __tm, __loc); +} + +// +// Other functions +// +inline _LIBCPP_HIDE_FROM_ABI decltype(MB_CUR_MAX) __mb_len_max(__locale_t __loc) { + __locale_guard __current(__loc); + return MB_CUR_MAX; +} + +# if _LIBCPP_HAS_WIDE_CHARACTERS +inline _LIBCPP_HIDE_FROM_ABI wint_t __btowc(int __c, __locale_t __loc) { + __locale_guard __current(__loc); + return std::btowc(__c); +} + +inline _LIBCPP_HIDE_FROM_ABI int __wctob(wint_t __c, __locale_t __loc) { + __locale_guard __current(__loc); + return std::wctob(__c); +} + +inline _LIBCPP_HIDE_FROM_ABI size_t +__wcsnrtombs(char* __dest, const wchar_t** __src, size_t __nwc, size_t __len, mbstate_t* __ps, __locale_t __loc) { + __locale_guard __current(__loc); + return ::wcsnrtombs(__dest, __src, __nwc, __len, __ps); // non-standard +} + +inline _LIBCPP_HIDE_FROM_ABI size_t __wcrtomb(char* __s, wchar_t __wc, mbstate_t* __ps, __locale_t __loc) { + __locale_guard __current(__loc); + return std::wcrtomb(__s, __wc, __ps); +} + +inline _LIBCPP_HIDE_FROM_ABI size_t +__mbsnrtowcs(wchar_t* __dest, const char** __src, size_t __nms, size_t __len, mbstate_t* __ps, __locale_t __loc) { + __locale_guard __current(__loc); + return ::mbsnrtowcs(__dest, __src, __nms, __len, __ps); // non-standard +} + +inline _LIBCPP_HIDE_FROM_ABI size_t +__mbrtowc(wchar_t* __pwc, const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) { + __locale_guard __current(__loc); + return std::mbrtowc(__pwc, __s, __n, __ps); +} + +inline _LIBCPP_HIDE_FROM_ABI int __mbtowc(wchar_t* __pwc, const char* __pmb, size_t __max, __locale_t __loc) { + __locale_guard __current(__loc); + return std::mbtowc(__pwc, __pmb, __max); +} + +inline _LIBCPP_HIDE_FROM_ABI size_t __mbrlen(const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) { + __locale_guard __current(__loc); + return std::mbrlen(__s, __n, __ps); +} + +inline _LIBCPP_HIDE_FROM_ABI size_t +__mbsrtowcs(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps, __locale_t __loc) { + __locale_guard __current(__loc); + return std::mbsrtowcs(__dest, __src, __len, __ps); +} +# endif // _LIBCPP_HAS_WIDE_CHARACTERS +#endif // _LIBCPP_BUILDING_LIBRARY + +#ifndef _LIBCPP_COMPILER_GCC // GCC complains that this can't be always_inline due to C-style varargs +_LIBCPP_HIDE_FROM_ABI +#endif +inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __snprintf( + char* __s, size_t __n, __locale_t __loc, const char* __format, ...) { + va_list __va; + va_start(__va, __format); + __locale_guard __current(__loc); + int __res = std::vsnprintf(__s, __n, __format, __va); + va_end(__va); + return __res; +} + +#ifndef _LIBCPP_COMPILER_GCC // GCC complains that this can't be always_inline due to C-style varargs +_LIBCPP_HIDE_FROM_ABI +#endif +inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf( + char** __s, __locale_t __loc, const char* __format, ...) { + va_list __va; + va_start(__va, __format); + __locale_guard __current(__loc); + int __res = ::vasprintf(__s, __format, __va); // non-standard + va_end(__va); + return __res; +} +} // namespace __locale +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___LOCALE_DIR_SUPPORT_NEWLIB_H diff --git a/libcxx/include/__locale_dir/support/no_locale/characters.h b/libcxx/include/__locale_dir/support/no_locale/characters.h index 1281b8b..73eba3e 100644 --- a/libcxx/include/__locale_dir/support/no_locale/characters.h +++ b/libcxx/include/__locale_dir/support/no_locale/characters.h @@ -29,10 +29,6 @@ namespace __locale { // // Character manipulation functions // -inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t) { return std::isdigit(__c); } - -inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t) { return std::isxdigit(__c); } - #if defined(_LIBCPP_BUILDING_LIBRARY) inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t) { return std::toupper(__c); } diff --git a/libcxx/include/__locale_dir/support/no_locale/strtonum.h b/libcxx/include/__locale_dir/support/no_locale/strtonum.h index 0e7a329..59544e1 100644 --- a/libcxx/include/__locale_dir/support/no_locale/strtonum.h +++ b/libcxx/include/__locale_dir/support/no_locale/strtonum.h @@ -34,15 +34,6 @@ inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __ return std::strtold(__nptr, __endptr); } -inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t) { - return std::strtoll(__nptr, __endptr, __base); -} - -inline _LIBCPP_HIDE_FROM_ABI unsigned long long -__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t) { - return std::strtoull(__nptr, __endptr, __base); -} - } // namespace __locale _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__locale_dir/support/windows.h b/libcxx/include/__locale_dir/support/windows.h index 0df8709..644ef68 100644 --- a/libcxx/include/__locale_dir/support/windows.h +++ b/libcxx/include/__locale_dir/support/windows.h @@ -186,21 +186,9 @@ inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr return ::_strtod_l(__nptr, __endptr, __loc); } -inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) { - return ::_strtoi64_l(__nptr, __endptr, __base, __loc); -} -inline _LIBCPP_HIDE_FROM_ABI unsigned long long -__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) { - return ::_strtoui64_l(__nptr, __endptr, __base, __loc); -} - // // Character manipulation functions // -inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t __loc) { return _isdigit_l(__c, __loc); } - -inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t __loc) { return _isxdigit_l(__c, __loc); } - #if defined(_LIBCPP_BUILDING_LIBRARY) inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return ::_toupper_l(__c, __loc); } @@ -280,23 +268,6 @@ _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __snpri _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf(char** __ret, __locale_t __loc, const char* __format, ...); -_LIBCPP_DIAGNOSTIC_PUSH -_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wgcc-compat") -_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") // GCC doesn't support [[gnu::format]] on variadic templates -#ifdef _LIBCPP_COMPILER_CLANG_BASED -# define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(...) _LIBCPP_ATTRIBUTE_FORMAT(__VA_ARGS__) -#else -# define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(...) /* nothing */ -#endif - -template <class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf( - const char* __dest, __locale_t __loc, const char* __format, _Args&&... __args) { - return ::_sscanf_l(__dest, __format, __loc, std::forward<_Args>(__args)...); -} -_LIBCPP_DIAGNOSTIC_POP -#undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT - #if defined(_LIBCPP_BUILDING_LIBRARY) struct __locale_guard { _LIBCPP_HIDE_FROM_ABI __locale_guard(__locale_t __l) : __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) { diff --git a/libcxx/include/__mdspan/extents.h b/libcxx/include/__mdspan/extents.h index 99b54ba..d16bbd2 100644 --- a/libcxx/include/__mdspan/extents.h +++ b/libcxx/include/__mdspan/extents.h @@ -25,6 +25,7 @@ #include <__type_traits/integer_traits.h> #include <__type_traits/is_convertible.h> #include <__type_traits/is_nothrow_constructible.h> +#include <__type_traits/is_signed.h> #include <__type_traits/make_unsigned.h> #include <__utility/integer_sequence.h> #include <__utility/unreachable.h> @@ -298,11 +299,13 @@ private: public: // [mdspan.extents.obs], observers of multidimensional index space - _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return __rank_; } - _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { return __rank_dynamic_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return __rank_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { return __rank_dynamic_; } - _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept { return __vals_.__value(__r); } - _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept { + return __vals_.__value(__r); + } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept { return _Values::__static_value(__r); } diff --git a/libcxx/include/__mdspan/mdspan.h b/libcxx/include/__mdspan/mdspan.h index c0f2767..9f3139a 100644 --- a/libcxx/include/__mdspan/mdspan.h +++ b/libcxx/include/__mdspan/mdspan.h @@ -87,12 +87,14 @@ public: using data_handle_type = typename accessor_type::data_handle_type; using reference = typename accessor_type::reference; - _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return extents_type::rank(); } - _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); } - _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return extents_type::rank(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { + return extents_type::rank_dynamic(); + } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept { return extents_type::static_extent(__r); } - _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept { return __map_.extents().extent(__r); }; @@ -185,7 +187,7 @@ public: requires((is_convertible_v<_OtherIndexTypes, index_type> && ...) && (is_nothrow_constructible_v<index_type, _OtherIndexTypes> && ...) && (sizeof...(_OtherIndexTypes) == rank())) - _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](_OtherIndexTypes... __indices) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](_OtherIndexTypes... __indices) const { // Note the standard layouts would also check this, but user provided ones may not, so we // check the precondition here _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__is_multidimensional_index_in(extents(), __indices...), @@ -196,7 +198,8 @@ public: template <class _OtherIndexType> requires(is_convertible_v<const _OtherIndexType&, index_type> && is_nothrow_constructible_v<index_type, const _OtherIndexType&>) - _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](const array< _OtherIndexType, rank()>& __indices) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference + operator[](const array< _OtherIndexType, rank()>& __indices) const { return __acc_.access(__ptr_, [&]<size_t... _Idxs>(index_sequence<_Idxs...>) { return __map_(__indices[_Idxs]...); }(make_index_sequence<rank()>())); @@ -205,7 +208,7 @@ public: template <class _OtherIndexType> requires(is_convertible_v<const _OtherIndexType&, index_type> && is_nothrow_constructible_v<index_type, const _OtherIndexType&>) - _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](span<_OtherIndexType, rank()> __indices) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](span<_OtherIndexType, rank()> __indices) const { return __acc_.access(__ptr_, [&]<size_t... _Idxs>(index_sequence<_Idxs...>) { return __map_(__indices[_Idxs]...); }(make_index_sequence<rank()>())); @@ -237,24 +240,28 @@ public: swap(__x.__acc_, __y.__acc_); } - _LIBCPP_HIDE_FROM_ABI constexpr const extents_type& extents() const noexcept { return __map_.extents(); }; - _LIBCPP_HIDE_FROM_ABI constexpr const data_handle_type& data_handle() const noexcept { return __ptr_; }; - _LIBCPP_HIDE_FROM_ABI constexpr const mapping_type& mapping() const noexcept { return __map_; }; - _LIBCPP_HIDE_FROM_ABI constexpr const accessor_type& accessor() const noexcept { return __acc_; }; + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const extents_type& extents() const noexcept { + return __map_.extents(); + }; + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const data_handle_type& data_handle() const noexcept { return __ptr_; }; + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const mapping_type& mapping() const noexcept { return __map_; }; + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const accessor_type& accessor() const noexcept { return __acc_; }; // per LWG-4021 "mdspan::is_always_meow() should be noexcept" - _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() noexcept { return mapping_type::is_always_unique(); }; - _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() noexcept { + return mapping_type::is_always_unique(); + }; + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() noexcept { return mapping_type::is_always_exhaustive(); }; - _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() noexcept { return mapping_type::is_always_strided(); }; - _LIBCPP_HIDE_FROM_ABI constexpr bool is_unique() const { return __map_.is_unique(); }; - _LIBCPP_HIDE_FROM_ABI constexpr bool is_exhaustive() const { return __map_.is_exhaustive(); }; - _LIBCPP_HIDE_FROM_ABI constexpr bool is_strided() const { return __map_.is_strided(); }; - _LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const { return __map_.stride(__r); }; + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool is_unique() const { return __map_.is_unique(); }; + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool is_exhaustive() const { return __map_.is_exhaustive(); }; + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool is_strided() const { return __map_.is_strided(); }; + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const { return __map_.stride(__r); }; private: _LIBCPP_NO_UNIQUE_ADDRESS data_handle_type __ptr_{}; diff --git a/libcxx/include/__memory/inout_ptr.h b/libcxx/include/__memory/inout_ptr.h index ef345fe..0fa685a 100644 --- a/libcxx/include/__memory/inout_ptr.h +++ b/libcxx/include/__memory/inout_ptr.h @@ -96,7 +96,7 @@ private: }; template <class _Pointer = void, class _Smart, class... _Args> -_LIBCPP_HIDE_FROM_ABI auto inout_ptr(_Smart& __s, _Args&&... __args) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto inout_ptr(_Smart& __s, _Args&&... __args) { using _Ptr = conditional_t<is_void_v<_Pointer>, __pointer_of_t<_Smart>, _Pointer>; return std::inout_ptr_t<_Smart, _Ptr, _Args&&...>(__s, std::forward<_Args>(__args)...); } diff --git a/libcxx/include/__memory/out_ptr.h b/libcxx/include/__memory/out_ptr.h index e498e33..23a77f6 100644 --- a/libcxx/include/__memory/out_ptr.h +++ b/libcxx/include/__memory/out_ptr.h @@ -88,7 +88,7 @@ private: }; template <class _Pointer = void, class _Smart, class... _Args> -_LIBCPP_HIDE_FROM_ABI auto out_ptr(_Smart& __s, _Args&&... __args) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto out_ptr(_Smart& __s, _Args&&... __args) { using _Ptr = conditional_t<is_void_v<_Pointer>, __pointer_of_t<_Smart>, _Pointer>; return std::out_ptr_t<_Smart, _Ptr, _Args&&...>(__s, std::forward<_Args>(__args)...); } diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h index e90db58..4fbd0af 100644 --- a/libcxx/include/__memory/shared_ptr.h +++ b/libcxx/include/__memory/shared_ptr.h @@ -41,13 +41,11 @@ #include <__type_traits/enable_if.h> #include <__type_traits/integral_constant.h> #include <__type_traits/is_array.h> -#include <__type_traits/is_bounded_array.h> #include <__type_traits/is_constructible.h> #include <__type_traits/is_convertible.h> #include <__type_traits/is_function.h> #include <__type_traits/is_reference.h> #include <__type_traits/is_same.h> -#include <__type_traits/is_unbounded_array.h> #include <__type_traits/nat.h> #include <__type_traits/negation.h> #include <__type_traits/remove_cv.h> @@ -79,7 +77,7 @@ public: _LIBCPP_HIDE_FROM_ABI bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default; _LIBCPP_HIDE_FROM_ABI bad_weak_ptr& operator=(const bad_weak_ptr&) _NOEXCEPT = default; ~bad_weak_ptr() _NOEXCEPT override; - const char* what() const _NOEXCEPT override; + [[__nodiscard__]] const char* what() const _NOEXCEPT override; }; [[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_weak_ptr() { @@ -317,10 +315,8 @@ public: #endif // A shared_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require - // any bookkeeping, so it's always trivially relocatable. It is also replaceable because assignment just rebinds the - // shared_ptr to manage a different object. + // any bookkeeping, so it's always trivially relocatable. using __trivially_relocatable _LIBCPP_NODEBUG = shared_ptr; - using __replaceable _LIBCPP_NODEBUG = shared_ptr; private: element_type* __ptr_; @@ -487,45 +483,16 @@ public: template <class _Yp, class _Dp, - __enable_if_t<!is_lvalue_reference<_Dp>::value && __compatible_with<_Yp, _Tp>::value && + __enable_if_t<__compatible_with<_Yp, _Tp>::value && is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI shared_ptr(unique_ptr<_Yp, _Dp>&& __r) : __ptr_(__r.get()) { -#if _LIBCPP_STD_VER >= 14 - if (__ptr_ == nullptr) - __cntrl_ = nullptr; - else -#endif - { - typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; - typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT> _CntrlBlk; - __cntrl_ = new _CntrlBlk(__r.get(), std::move(__r.get_deleter()), _AllocT()); - __enable_weak_this(__r.get(), __r.get()); - } - __r.release(); - } + using _AllocT = typename __shared_ptr_default_allocator<_Yp>::type; + using _Deleter = _If<is_lvalue_reference<_Dp>::value, reference_wrapper<__libcpp_remove_reference_t<_Dp> >, _Dp>; + using _CntrlBlk = __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Deleter, _AllocT>; - template <class _Yp, - class _Dp, - class = void, - __enable_if_t<is_lvalue_reference<_Dp>::value && __compatible_with<_Yp, _Tp>::value && - is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, - int> = 0> - _LIBCPP_HIDE_FROM_ABI shared_ptr(unique_ptr<_Yp, _Dp>&& __r) : __ptr_(__r.get()) { -#if _LIBCPP_STD_VER >= 14 - if (__ptr_ == nullptr) - __cntrl_ = nullptr; - else -#endif - { - typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; - typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, - reference_wrapper<__libcpp_remove_reference_t<_Dp> >, - _AllocT> - _CntrlBlk; - __cntrl_ = new _CntrlBlk(__r.get(), std::ref(__r.get_deleter()), _AllocT()); - __enable_weak_this(__r.get(), __r.get()); - } + __cntrl_ = __ptr_ ? new _CntrlBlk(__r.get(), std::forward<_Dp>(__r.get_deleter()), _AllocT()) : nullptr; + __enable_weak_this(__r.get(), __r.get()); __r.release(); } @@ -601,37 +568,43 @@ public: shared_ptr(__p, __d, __a).swap(*this); } - _LIBCPP_HIDE_FROM_ABI element_type* get() const _NOEXCEPT { return __ptr_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI element_type* get() const _NOEXCEPT { return __ptr_; } - _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator*() const _NOEXCEPT { return *__ptr_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator*() const _NOEXCEPT { + return *__ptr_; + } _LIBCPP_HIDE_FROM_ABI element_type* operator->() const _NOEXCEPT { static_assert(!is_array<_Tp>::value, "std::shared_ptr<T>::operator-> is only valid when T is not an array type."); return __ptr_; } - _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __cntrl_ ? __cntrl_->use_count() : 0; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { + return __cntrl_ ? __cntrl_->use_count() : 0; + } #if _LIBCPP_STD_VER < 20 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE) - _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI bool unique() const _NOEXCEPT { return use_count() == 1; } + [[__nodiscard__]] _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI bool unique() const _NOEXCEPT { + return use_count() == 1; + } #endif _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return get() != nullptr; } template <class _Up> - _LIBCPP_HIDE_FROM_ABI bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT { return __cntrl_ < __p.__cntrl_; } template <class _Up> - _LIBCPP_HIDE_FROM_ABI bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT { return __cntrl_ < __p.__cntrl_; } _LIBCPP_HIDE_FROM_ABI bool __owner_equivalent(const shared_ptr& __p) const { return __cntrl_ == __p.__cntrl_; } #if _LIBCPP_STD_VER >= 17 - _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const { static_assert(is_array<_Tp>::value, "std::shared_ptr<T>::operator[] is only valid when T is an array type."); return __ptr_[__i]; } @@ -702,7 +675,7 @@ shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>; // std::allocate_shared and std::make_shared // template <class _Tp, class _Alloc, class... _Args, __enable_if_t<!is_array<_Tp>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&... __args) { +[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&... __args) { using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>; using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type; __allocation_guard<_ControlBlockAllocator> __guard(__a, 1); @@ -713,21 +686,21 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&& } template <class _Tp, class... _Args, __enable_if_t<!is_array<_Tp>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(_Args&&... __args) { +[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(_Args&&... __args) { return std::allocate_shared<_Tp>(allocator<__remove_cv_t<_Tp> >(), std::forward<_Args>(__args)...); } #if _LIBCPP_STD_VER >= 20 template <class _Tp, class _Alloc, __enable_if_t<!is_array<_Tp>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) { using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>; _ForOverwriteAllocator __alloc(__a); return std::allocate_shared<_Tp>(__alloc); } template <class _Tp, __enable_if_t<!is_array<_Tp>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() { return std::allocate_shared_for_overwrite<_Tp>(allocator<__remove_cv_t<_Tp>>()); } @@ -919,67 +892,69 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Array> __allocate_shared_bounded_array(const _ // bounded array variants template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a) { return std::__allocate_shared_bounded_array<_Tp>(__a); } template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& __u) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> +allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& __u) { return std::__allocate_shared_bounded_array<_Tp>(__a, __u); } template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) { using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>; _ForOverwriteAllocator __alloc(__a); return std::__allocate_shared_bounded_array<_Tp>(__alloc); } template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared() { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared() { return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>()); } template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(const remove_extent_t<_Tp>& __u) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(const remove_extent_t<_Tp>& __u) { return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>(), __u); } template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() { return std::__allocate_shared_bounded_array<_Tp>(allocator<__for_overwrite_tag>()); } // unbounded array variants template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n) { return std::__allocate_shared_unbounded_array<_Tp>(__a, __n); } template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> +allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u) { return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __u); } template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n) { using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>; _ForOverwriteAllocator __alloc(__a); return std::__allocate_shared_unbounded_array<_Tp>(__alloc, __n); } template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n) { return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n); } template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n, const remove_extent_t<_Tp>& __u) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n, const remove_extent_t<_Tp>& __u) { return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n, __u); } template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite(size_t __n) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite(size_t __n) { return std::__allocate_shared_unbounded_array<_Tp>(allocator<__for_overwrite_tag>(), __n); } @@ -1108,7 +1083,8 @@ inline _LIBCPP_HIDE_FROM_ABI void swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __ } template <class _Tp, class _Up> -inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> +static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT { return shared_ptr<_Tp>(__r, static_cast< typename shared_ptr<_Tp>::element_type*>(__r.get())); } @@ -1116,13 +1092,14 @@ inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(const shared_pt // We don't backport because it is an evolutionary change. #if _LIBCPP_STD_VER >= 20 template <class _Tp, class _Up> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(shared_ptr<_Up>&& __r) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(shared_ptr<_Up>&& __r) noexcept { return shared_ptr<_Tp>(std::move(__r), static_cast<typename shared_ptr<_Tp>::element_type*>(__r.get())); } #endif template <class _Tp, class _Up> -inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT { +[[__nodiscard__]] inline + _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT { typedef typename shared_ptr<_Tp>::element_type _ET; _ET* __p = dynamic_cast<_ET*>(__r.get()); return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>(); @@ -1132,14 +1109,14 @@ inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_p // We don't backport because it is an evolutionary change. #if _LIBCPP_STD_VER >= 20 template <class _Tp, class _Up> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept { auto* __p = dynamic_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()); return __p ? shared_ptr<_Tp>(std::move(__r), __p) : shared_ptr<_Tp>(); } #endif template <class _Tp, class _Up> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT { +[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT { typedef typename shared_ptr<_Tp>::element_type _RTp; return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get())); } @@ -1148,13 +1125,13 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>& // We don't backport because it is an evolutionary change. #if _LIBCPP_STD_VER >= 20 template <class _Tp, class _Up> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(shared_ptr<_Up>&& __r) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(shared_ptr<_Up>&& __r) noexcept { return shared_ptr<_Tp>(std::move(__r), const_cast<typename shared_ptr<_Tp>::element_type*>(__r.get())); } #endif template <class _Tp, class _Up> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT { +[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT { return shared_ptr<_Tp>(__r, reinterpret_cast< typename shared_ptr<_Tp>::element_type*>(__r.get())); } @@ -1162,7 +1139,7 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr< // We don't backport because it is an evolutionary change. #if _LIBCPP_STD_VER >= 20 template <class _Tp, class _Up> -_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept { return shared_ptr<_Tp>(std::move(__r), reinterpret_cast<typename shared_ptr<_Tp>::element_type*>(__r.get())); } #endif @@ -1170,7 +1147,7 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&& #if _LIBCPP_HAS_RTTI template <class _Dp, class _Tp> -inline _LIBCPP_HIDE_FROM_ABI _Dp* get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _Dp* get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT { return __p.template __get_deleter<_Dp>(); } @@ -1186,9 +1163,8 @@ public: #endif // A weak_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require - // any bookkeeping, so it's always trivially relocatable. It's also replaceable for the same reason. + // any bookkeeping, so it's always trivially relocatable. using __trivially_relocatable _LIBCPP_NODEBUG = weak_ptr; - using __replaceable _LIBCPP_NODEBUG = weak_ptr; private: element_type* __ptr_; @@ -1226,15 +1202,19 @@ public: _LIBCPP_HIDE_FROM_ABI void swap(weak_ptr& __r) _NOEXCEPT; _LIBCPP_HIDE_FROM_ABI void reset() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __cntrl_ ? __cntrl_->use_count() : 0; } - _LIBCPP_HIDE_FROM_ABI bool expired() const _NOEXCEPT { return __cntrl_ == nullptr || __cntrl_->use_count() == 0; } - _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> lock() const _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { + return __cntrl_ ? __cntrl_->use_count() : 0; + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool expired() const _NOEXCEPT { + return __cntrl_ == nullptr || __cntrl_->use_count() == 0; + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> lock() const _NOEXCEPT; template <class _Up> - _LIBCPP_HIDE_FROM_ABI bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT { return __cntrl_ < __r.__cntrl_; } template <class _Up> - _LIBCPP_HIDE_FROM_ABI bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT { return __cntrl_ < __r.__cntrl_; } @@ -1418,13 +1398,15 @@ protected: _LIBCPP_HIDE_FROM_ABI ~enable_shared_from_this() {} public: - _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> shared_from_this() { return shared_ptr<_Tp>(__weak_this_); } - _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp const> shared_from_this() const { return shared_ptr<const _Tp>(__weak_this_); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> shared_from_this() { return shared_ptr<_Tp>(__weak_this_); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp const> shared_from_this() const { + return shared_ptr<const _Tp>(__weak_this_); + } #if _LIBCPP_STD_VER >= 17 - _LIBCPP_HIDE_FROM_ABI weak_ptr<_Tp> weak_from_this() _NOEXCEPT { return __weak_this_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI weak_ptr<_Tp> weak_from_this() _NOEXCEPT { return __weak_this_; } - _LIBCPP_HIDE_FROM_ABI weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT { return __weak_this_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT { return __weak_this_; } #endif // _LIBCPP_STD_VER >= 17 template <class _Up> @@ -1441,7 +1423,7 @@ struct hash<shared_ptr<_Tp> > { _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; #endif - _LIBCPP_HIDE_FROM_ABI size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT { return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get()); } }; diff --git a/libcxx/include/__memory/temp_value.h b/libcxx/include/__memory/temp_value.h index 4a133b3..5285bcab 100644 --- a/libcxx/include/__memory/temp_value.h +++ b/libcxx/include/__memory/temp_value.h @@ -12,7 +12,6 @@ #include <__config> #include <__memory/addressof.h> #include <__memory/allocator_traits.h> -#include <__type_traits/aligned_storage.h> #include <__utility/forward.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -26,7 +25,7 @@ struct __temp_value { typedef allocator_traits<_Alloc> _Traits; #ifdef _LIBCPP_CXX03_LANG - typename aligned_storage<sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)>::type __v; + _ALIGNAS_TYPE(_Tp) char __v[sizeof(_Tp)]; #else union { _Tp __v; diff --git a/libcxx/include/__memory/uninitialized_algorithms.h b/libcxx/include/__memory/uninitialized_algorithms.h index 34d065d..9182db4 100644 --- a/libcxx/include/__memory/uninitialized_algorithms.h +++ b/libcxx/include/__memory/uninitialized_algorithms.h @@ -32,7 +32,6 @@ #include <__type_traits/is_trivially_assignable.h> #include <__type_traits/is_trivially_constructible.h> #include <__type_traits/is_trivially_relocatable.h> -#include <__type_traits/is_unbounded_array.h> #include <__type_traits/remove_const.h> #include <__type_traits/remove_extent.h> #include <__utility/exception_guard.h> diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h index eff2454..6a4ec0a 100644 --- a/libcxx/include/__memory/unique_ptr.h +++ b/libcxx/include/__memory/unique_ptr.h @@ -32,18 +32,15 @@ #include <__type_traits/integral_constant.h> #include <__type_traits/is_array.h> #include <__type_traits/is_assignable.h> -#include <__type_traits/is_bounded_array.h> #include <__type_traits/is_constant_evaluated.h> #include <__type_traits/is_constructible.h> #include <__type_traits/is_convertible.h> #include <__type_traits/is_function.h> #include <__type_traits/is_pointer.h> #include <__type_traits/is_reference.h> -#include <__type_traits/is_replaceable.h> #include <__type_traits/is_same.h> #include <__type_traits/is_swappable.h> #include <__type_traits/is_trivially_relocatable.h> -#include <__type_traits/is_unbounded_array.h> #include <__type_traits/is_void.h> #include <__type_traits/remove_extent.h> #include <__type_traits/type_identity.h> @@ -145,8 +142,6 @@ public: __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value, unique_ptr, void>; - using __replaceable _LIBCPP_NODEBUG = - __conditional_t<__is_replaceable_v<pointer> && __is_replaceable_v<deleter_type>, unique_ptr, void>; private: _LIBCPP_COMPRESSED_PAIR(pointer, __ptr_, deleter_type, __deleter_); @@ -263,14 +258,17 @@ public: return *this; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const _NOEXCEPT_(_NOEXCEPT_(*std::declval<pointer>())) { return *__ptr_; } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT { return __ptr_; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __deleter_; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { + return __deleter_; + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& + get_deleter() const _NOEXCEPT { return __deleter_; } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT { @@ -413,8 +411,6 @@ public: __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value, unique_ptr, void>; - using __replaceable _LIBCPP_NODEBUG = - __conditional_t<__is_replaceable_v<pointer> && __is_replaceable_v<deleter_type>, unique_ptr, void>; private: template <class _Up, class _OtherDeleter> @@ -755,12 +751,13 @@ operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { #if _LIBCPP_STD_VER >= 14 template <class _Tp, class... _Args, enable_if_t<!is_array<_Tp>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(_Args&&... __args) { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(_Args&&... __args) { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); } template <class _Tp, enable_if_t<__is_unbounded_array_v<_Tp>, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(size_t __n) { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(size_t __n) { typedef __remove_extent_t<_Tp> _Up; return unique_ptr<_Tp>(__private_constructor_tag(), new _Up[__n](), __n); } @@ -773,12 +770,13 @@ void make_unique(_Args&&...) = delete; #if _LIBCPP_STD_VER >= 20 template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite() { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite() { return unique_ptr<_Tp>(new _Tp); } template <class _Tp, enable_if_t<is_unbounded_array_v<_Tp>, int> = 0> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite(size_t __n) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> +make_unique_for_overwrite(size_t __n) { return unique_ptr<_Tp>(__private_constructor_tag(), new __remove_extent_t<_Tp>[__n], __n); } @@ -802,7 +800,7 @@ struct hash<__enable_hash_helper< unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; #endif - _LIBCPP_HIDE_FROM_ABI size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const { typedef typename unique_ptr<_Tp, _Dp>::pointer pointer; return hash<pointer>()(__ptr.get()); } diff --git a/libcxx/include/__mutex/mutex.h b/libcxx/include/__mutex/mutex.h index 68c8842..e9cedf8 100644 --- a/libcxx/include/__mutex/mutex.h +++ b/libcxx/include/__mutex/mutex.h @@ -37,11 +37,11 @@ public: # endif _LIBCPP_ACQUIRE_CAPABILITY() void lock(); - _LIBCPP_TRY_ACQUIRE_CAPABILITY(true) bool try_lock() _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_TRY_ACQUIRE_CAPABILITY(true) bool try_lock() _NOEXCEPT; _LIBCPP_RELEASE_CAPABILITY void unlock() _NOEXCEPT; typedef __libcpp_mutex_t* native_handle_type; - _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; } }; static_assert(is_nothrow_default_constructible<mutex>::value, "the default constructor for std::mutex must be nothrow"); diff --git a/libcxx/include/__mutex/once_flag.h b/libcxx/include/__mutex/once_flag.h index 808b1ea..ad15b2e 100644 --- a/libcxx/include/__mutex/once_flag.h +++ b/libcxx/include/__mutex/once_flag.h @@ -86,12 +86,10 @@ class __call_once_param { public: _LIBCPP_HIDE_FROM_ABI explicit __call_once_param(_Fp& __f) : __f_(__f) {} - _LIBCPP_HIDE_FROM_ABI void operator()() { __execute(__make_index_sequence<tuple_size<_Fp>::value>()); } - -private: - template <size_t... _Indices> - _LIBCPP_HIDE_FROM_ABI void __execute(__index_sequence<_Indices...>) { - std::__invoke(std::get<_Indices>(std::move(__f_))...); + _LIBCPP_HIDE_FROM_ABI void operator()() { + [&]<size_t... _Indices>(__index_sequence<_Indices...>) -> void { + std::__invoke(std::get<_Indices>(std::move(__f_))...); + }(__make_index_sequence<tuple_size<_Fp>::value>()); } }; diff --git a/libcxx/include/__random/binomial_distribution.h b/libcxx/include/__random/binomial_distribution.h index bada8cf..0712e4ef 100644 --- a/libcxx/include/__random/binomial_distribution.h +++ b/libcxx/include/__random/binomial_distribution.h @@ -98,13 +98,7 @@ public: }; // Some libc declares the math functions to be `noexcept`. -#if defined(_LIBCPP_GLIBC_PREREQ) -# if _LIBCPP_GLIBC_PREREQ(2, 8) -# define _LIBCPP_LGAMMA_R_NOEXCEPT _NOEXCEPT -# else -# define _LIBCPP_LGAMMA_R_NOEXCEPT -# endif -#elif defined(__LLVM_LIBC__) +#if _LIBCPP_GLIBC_PREREQ(2, 8) || defined(__LLVM_LIBC__) # define _LIBCPP_LGAMMA_R_NOEXCEPT _NOEXCEPT #else # define _LIBCPP_LGAMMA_R_NOEXCEPT diff --git a/libcxx/include/__random/mersenne_twister_engine.h b/libcxx/include/__random/mersenne_twister_engine.h index c60fe15..332e830 100644 --- a/libcxx/include/__random/mersenne_twister_engine.h +++ b/libcxx/include/__random/mersenne_twister_engine.h @@ -62,24 +62,6 @@ _LIBCPP_HIDE_FROM_ABI bool operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x, const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y); -template <class _UInt, - size_t _Wp, - size_t _Np, - size_t _Mp, - size_t _Rp, - _UInt _Ap, - size_t _Up, - _UInt _Dp, - size_t _Sp, - _UInt _Bp, - size_t _Tp, - _UInt _Cp, - size_t _Lp, - _UInt _Fp> -_LIBCPP_HIDE_FROM_ABI bool -operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x, - const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y); - template <class _CharT, class _Traits, class _UInt, @@ -194,14 +176,31 @@ public: _LIBCPP_HIDE_FROM_ABI explicit mersenne_twister_engine(_Sseq& __q) { seed(__q); } - _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd = default_seed); + _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd = default_seed) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { + __x_[0] = __sd & _Max; + for (size_t __i = 1; __i < __n; ++__i) + __x_[__i] = (__f * (__x_[__i - 1] ^ __rshift<__w - 2>(__x_[__i - 1])) + __i) & _Max; + __i_ = 0; + } template <class _Sseq, __enable_if_t<__is_seed_sequence<_Sseq, mersenne_twister_engine>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI void seed(_Sseq& __q) { __seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>()); } // generating functions - _LIBCPP_HIDE_FROM_ABI result_type operator()(); + _LIBCPP_HIDE_FROM_ABI result_type operator()() { + const size_t __j = (__i_ + 1) % __n; + const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1); + const result_type __yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask); + const size_t __k = (__i_ + __m) % __n; + __x_[__i_] = __x_[__k] ^ __rshift<1>(__yp) ^ (__a * (__yp & 1)); + result_type __z = __x_[__i_] ^ (__rshift<__u>(__x_[__i_]) & __d); + __i_ = __j; + __z ^= __lshift<__s>(__z) & __b; + __z ^= __lshift<__t>(__z) & __c; + return __z ^ __rshift<__l>(__z); + } + _LIBCPP_HIDE_FROM_ABI void discard(unsigned long long __z) { for (; __z; --__z) operator()(); @@ -225,24 +224,6 @@ public: const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x, const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y); - template <class _UInt, - size_t _Wp, - size_t _Np, - size_t _Mp, - size_t _Rp, - _UInt _Ap, - size_t _Up, - _UInt _Dp, - size_t _Sp, - _UInt _Bp, - size_t _Tp, - _UInt _Cp, - size_t _Lp, - _UInt _Fp> - friend bool operator!=( - const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x, - const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y); - template <class _CharT, class _Traits, class _UInt, @@ -285,9 +266,38 @@ public: private: template <class _Sseq> - _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>); + _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>) { + const unsigned __k = 1; + uint32_t __ar[__n * __k]; + __q.generate(__ar, __ar + __n * __k); + for (size_t __i = 0; __i < __n; ++__i) + __x_[__i] = static_cast<result_type>(__ar[__i] & _Max); + const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1); + __i_ = 0; + if ((__x_[0] & ~__mask) == 0) { + for (size_t __i = 1; __i < __n; ++__i) + if (__x_[__i] != 0) + return; + __x_[0] = result_type(1) << (__w - 1); + } + } + template <class _Sseq> - _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>); + _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>) { + const unsigned __k = 2; + uint32_t __ar[__n * __k]; + __q.generate(__ar, __ar + __n * __k); + for (size_t __i = 0; __i < __n; ++__i) + __x_[__i] = static_cast<result_type>((__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max); + const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1); + __i_ = 0; + if ((__x_[0] & ~__mask) == 0) { + for (size_t __i = 1; __i < __n; ++__i) + if (__x_[__i] != 0) + return; + __x_[0] = result_type(1) << (__w - 1); + } + } template <size_t __count, __enable_if_t<__count< __w, int> = 0> _LIBCPP_HIDE_FROM_ABI static result_type __lshift(result_type __x) { @@ -310,120 +320,6 @@ private: } }; -template <class _UIntType, - size_t __w, - size_t __n, - size_t __m, - size_t __r, - _UIntType __a, - size_t __u, - _UIntType __d, - size_t __s, - _UIntType __b, - size_t __t, - _UIntType __c, - size_t __l, - _UIntType __f> -void mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::seed( - result_type __sd) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { // __w >= 2 - __x_[0] = __sd & _Max; - for (size_t __i = 1; __i < __n; ++__i) - __x_[__i] = (__f * (__x_[__i - 1] ^ __rshift<__w - 2>(__x_[__i - 1])) + __i) & _Max; - __i_ = 0; -} - -template <class _UIntType, - size_t __w, - size_t __n, - size_t __m, - size_t __r, - _UIntType __a, - size_t __u, - _UIntType __d, - size_t __s, - _UIntType __b, - size_t __t, - _UIntType __c, - size_t __l, - _UIntType __f> -template <class _Sseq> -void mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::__seed( - _Sseq& __q, integral_constant<unsigned, 1>) { - const unsigned __k = 1; - uint32_t __ar[__n * __k]; - __q.generate(__ar, __ar + __n * __k); - for (size_t __i = 0; __i < __n; ++__i) - __x_[__i] = static_cast<result_type>(__ar[__i] & _Max); - const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1); - __i_ = 0; - if ((__x_[0] & ~__mask) == 0) { - for (size_t __i = 1; __i < __n; ++__i) - if (__x_[__i] != 0) - return; - __x_[0] = result_type(1) << (__w - 1); - } -} - -template <class _UIntType, - size_t __w, - size_t __n, - size_t __m, - size_t __r, - _UIntType __a, - size_t __u, - _UIntType __d, - size_t __s, - _UIntType __b, - size_t __t, - _UIntType __c, - size_t __l, - _UIntType __f> -template <class _Sseq> -void mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::__seed( - _Sseq& __q, integral_constant<unsigned, 2>) { - const unsigned __k = 2; - uint32_t __ar[__n * __k]; - __q.generate(__ar, __ar + __n * __k); - for (size_t __i = 0; __i < __n; ++__i) - __x_[__i] = static_cast<result_type>((__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max); - const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1); - __i_ = 0; - if ((__x_[0] & ~__mask) == 0) { - for (size_t __i = 1; __i < __n; ++__i) - if (__x_[__i] != 0) - return; - __x_[0] = result_type(1) << (__w - 1); - } -} - -template <class _UIntType, - size_t __w, - size_t __n, - size_t __m, - size_t __r, - _UIntType __a, - size_t __u, - _UIntType __d, - size_t __s, - _UIntType __b, - size_t __t, - _UIntType __c, - size_t __l, - _UIntType __f> -_UIntType -mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::operator()() { - const size_t __j = (__i_ + 1) % __n; - const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1); - const result_type __yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask); - const size_t __k = (__i_ + __m) % __n; - __x_[__i_] = __x_[__k] ^ __rshift<1>(__yp) ^ (__a * (__yp & 1)); - result_type __z = __x_[__i_] ^ (__rshift<__u>(__x_[__i_]) & __d); - __i_ = __j; - __z ^= __lshift<__s>(__z) & __b; - __z ^= __lshift<__t>(__z) & __c; - return __z ^ __rshift<__l>(__z); -} - template <class _UInt, size_t _Wp, size_t _Np, diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h index 22adc22..f66f3f9 100644 --- a/libcxx/include/__ranges/iota_view.h +++ b/libcxx/include/__ranges/iota_view.h @@ -58,11 +58,17 @@ struct __get_wider_signed { return type_identity<int>{}; else if constexpr (sizeof(_Int) < sizeof(long)) return type_identity<long>{}; - else + else if constexpr (sizeof(_Int) < sizeof(long long)) return type_identity<long long>{}; - - static_assert( - sizeof(_Int) <= sizeof(long long), "Found integer-like type that is bigger than largest integer like type."); +# if _LIBCPP_HAS_INT128 + else if constexpr (sizeof(_Int) <= sizeof(__int128)) + return type_identity<__int128>{}; +# else + else if constexpr (sizeof(_Int) <= sizeof(long long)) + return type_identity<long long>{}; +# endif + else + static_assert(false, "Found integer-like type that is bigger than the largest integer like type."); } using type = typename decltype(__call())::type; diff --git a/libcxx/include/__split_buffer b/libcxx/include/__split_buffer index 15368a3..1e05e4d 100644 --- a/libcxx/include/__split_buffer +++ b/libcxx/include/__split_buffer @@ -30,7 +30,6 @@ #include <__type_traits/integral_constant.h> #include <__type_traits/is_nothrow_assignable.h> #include <__type_traits/is_nothrow_constructible.h> -#include <__type_traits/is_replaceable.h> #include <__type_traits/is_swappable.h> #include <__type_traits/is_trivially_destructible.h> #include <__type_traits/is_trivially_relocatable.h> @@ -484,10 +483,6 @@ public: __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<allocator_type>::value, __split_buffer, void>; - using __replaceable _LIBCPP_NODEBUG = - __conditional_t<__is_replaceable_v<pointer> && __container_allocator_is_replaceable<__alloc_traits>::value, - __split_buffer, - void>; __split_buffer(const __split_buffer&) = delete; __split_buffer& operator=(const __split_buffer&) = delete; diff --git a/libcxx/include/__support/xlocale/__strtonum_fallback.h b/libcxx/include/__support/xlocale/__strtonum_fallback.h index 5275aea..90bd59d 100644 --- a/libcxx/include/__support/xlocale/__strtonum_fallback.h +++ b/libcxx/include/__support/xlocale/__strtonum_fallback.h @@ -34,12 +34,4 @@ inline _LIBCPP_HIDE_FROM_ABI long double strtold_l(const char* __nptr, char** __ return ::strtold(__nptr, __endptr); } -inline _LIBCPP_HIDE_FROM_ABI long long strtoll_l(const char* __nptr, char** __endptr, int __base, locale_t) { - return ::strtoll(__nptr, __endptr, __base); -} - -inline _LIBCPP_HIDE_FROM_ABI unsigned long long strtoull_l(const char* __nptr, char** __endptr, int __base, locale_t) { - return ::strtoull(__nptr, __endptr, __base); -} - #endif // _LIBCPP___SUPPORT_XLOCALE_STRTONUM_FALLBACK_H diff --git a/libcxx/include/__system_error/error_category.h b/libcxx/include/__system_error/error_category.h index 191f4d8..7f7c735 100644 --- a/libcxx/include/__system_error/error_category.h +++ b/libcxx/include/__system_error/error_category.h @@ -37,11 +37,11 @@ public: error_category(const error_category&) = delete; error_category& operator=(const error_category&) = delete; - virtual const char* name() const _NOEXCEPT = 0; - virtual error_condition default_error_condition(int __ev) const _NOEXCEPT; - virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT; - virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT; - virtual string message(int __ev) const = 0; + [[__nodiscard__]] virtual const char* name() const _NOEXCEPT = 0; + [[__nodiscard__]] virtual error_condition default_error_condition(int __ev) const _NOEXCEPT; + [[__nodiscard__]] virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT; + [[__nodiscard__]] virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT; + [[__nodiscard__]] virtual string message(int __ev) const = 0; _LIBCPP_HIDE_FROM_ABI bool operator==(const error_category& __rhs) const _NOEXCEPT { return this == &__rhs; } @@ -67,8 +67,8 @@ public: string message(int __ev) const override; }; -[[__gnu__::__const__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& generic_category() _NOEXCEPT; -[[__gnu__::__const__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& system_category() _NOEXCEPT; +[[__gnu__::__const__]] [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& generic_category() _NOEXCEPT; +[[__gnu__::__const__]] [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& system_category() _NOEXCEPT; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__system_error/error_code.h b/libcxx/include/__system_error/error_code.h index f6ea40d..e904376 100644 --- a/libcxx/include/__system_error/error_code.h +++ b/libcxx/include/__system_error/error_code.h @@ -71,20 +71,20 @@ public: __cat_ = &system_category(); } - _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; } - _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; } - _LIBCPP_HIDE_FROM_ABI error_condition default_error_condition() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI error_condition default_error_condition() const _NOEXCEPT { return __cat_->default_error_condition(__val_); } - string message() const; + [[__nodiscard__]] string message() const; _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __val_ != 0; } }; -inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(errc __e) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(errc __e) _NOEXCEPT { return error_code(static_cast<int>(__e), generic_category()); } diff --git a/libcxx/include/__system_error/error_condition.h b/libcxx/include/__system_error/error_condition.h index 34819f4..be7deab 100644 --- a/libcxx/include/__system_error/error_condition.h +++ b/libcxx/include/__system_error/error_condition.h @@ -80,15 +80,15 @@ public: __cat_ = &generic_category(); } - _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; } - _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; } - string message() const; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; } + [[__nodiscard__]] string message() const; _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __val_ != 0; } }; -inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(errc __e) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(errc __e) _NOEXCEPT { return error_condition(static_cast<int>(__e), generic_category()); } diff --git a/libcxx/include/__system_error/system_error.h b/libcxx/include/__system_error/system_error.h index 36ccf94..74427d8 100644 --- a/libcxx/include/__system_error/system_error.h +++ b/libcxx/include/__system_error/system_error.h @@ -36,7 +36,7 @@ public: _LIBCPP_HIDE_FROM_ABI system_error(const system_error&) _NOEXCEPT = default; ~system_error() _NOEXCEPT override; - _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; } }; // __ev is expected to be an error in the generic_category domain (e.g. from diff --git a/libcxx/include/__thread/thread.h b/libcxx/include/__thread/thread.h index a3b672b..561f092 100644 --- a/libcxx/include/__thread/thread.h +++ b/libcxx/include/__thread/thread.h @@ -242,13 +242,13 @@ public: _LIBCPP_HIDE_FROM_ABI void swap(thread& __t) _NOEXCEPT { std::swap(__t_, __t.__t_); } - _LIBCPP_HIDE_FROM_ABI bool joinable() const _NOEXCEPT { return !__libcpp_thread_isnull(&__t_); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool joinable() const _NOEXCEPT { return !__libcpp_thread_isnull(&__t_); } void join(); void detach(); - _LIBCPP_HIDE_FROM_ABI id get_id() const _NOEXCEPT { return __libcpp_thread_get_id(&__t_); } - _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() _NOEXCEPT { return __t_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI id get_id() const _NOEXCEPT { return __libcpp_thread_get_id(&__t_); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() _NOEXCEPT { return __t_; } - static unsigned hardware_concurrency() _NOEXCEPT; + [[__nodiscard__]] static unsigned hardware_concurrency() _NOEXCEPT; }; inline _LIBCPP_HIDE_FROM_ABI void swap(thread& __x, thread& __y) _NOEXCEPT { __x.swap(__y); } diff --git a/libcxx/include/__tree b/libcxx/include/__tree index 6947969..ceae22b 100644 --- a/libcxx/include/__tree +++ b/libcxx/include/__tree @@ -887,6 +887,18 @@ public: } _LIBCPP_HIDE_FROM_ABI __tree(const __tree& __t); + + _LIBCPP_HIDE_FROM_ABI __tree(const __tree& __other, const allocator_type& __alloc) + : __begin_node_(__end_node()), __node_alloc_(__alloc), __size_(0), __value_comp_(__other.value_comp()) { + if (__other.size() == 0) + return; + + *__root_ptr() = static_cast<__node_base_pointer>(__copy_construct_tree(__other.__root())); + __root()->__parent_ = __end_node(); + __begin_node_ = static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_)); + __size_ = __other.size(); + } + _LIBCPP_HIDE_FROM_ABI __tree& operator=(const __tree& __t); template <class _ForwardIterator> _LIBCPP_HIDE_FROM_ABI void __assign_unique(_ForwardIterator __first, _ForwardIterator __last); @@ -995,27 +1007,6 @@ public: std::forward<_Args>(__args)...); } - template <class _ValueT = _Tp, __enable_if_t<__is_tree_value_type_v<_ValueT>, int> = 0> - _LIBCPP_HIDE_FROM_ABI void - __insert_unique_from_orphaned_node(const_iterator __p, __get_node_value_type_t<_Tp>&& __value) { - __emplace_hint_unique(__p, const_cast<key_type&&>(__value.first), std::move(__value.second)); - } - - template <class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type_v<_ValueT>, int> = 0> - _LIBCPP_HIDE_FROM_ABI void __insert_unique_from_orphaned_node(const_iterator __p, _Tp&& __value) { - __emplace_hint_unique(__p, std::move(__value)); - } - - template <class _ValueT = _Tp, __enable_if_t<__is_tree_value_type_v<_ValueT>, int> = 0> - _LIBCPP_HIDE_FROM_ABI void __insert_multi_from_orphaned_node(const_iterator __p, value_type&& __value) { - __emplace_hint_multi(__p, const_cast<key_type&&>(__value.first), std::move(__value.second)); - } - - template <class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type_v<_ValueT>, int> = 0> - _LIBCPP_HIDE_FROM_ABI void __insert_multi_from_orphaned_node(const_iterator __p, _Tp&& __value) { - __emplace_hint_multi(__p, std::move(__value)); - } - template <class _InIter, class _Sent> _LIBCPP_HIDE_FROM_ABI void __insert_range_multi(_InIter __first, _Sent __last) { if (__first == __last) @@ -1388,19 +1379,19 @@ private: // copy the exact structure 1:1. Since this is for copy construction _only_ we know that we get a correct tree. If we // didn't get a correct tree, the invariants of __tree are broken and we have a much bigger problem than an improperly // balanced tree. + template <class _NodeConstructor> #ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function _LIBCPP_HIDE_FROM_ABI #endif - __node_pointer - __copy_construct_tree(__node_pointer __src) { + __node_pointer __construct_from_tree(__node_pointer __src, _NodeConstructor __construct) { if (!__src) return nullptr; - __node_holder __new_node = __construct_node(__src->__get_value()); + __node_holder __new_node = __construct(__src->__get_value()); unique_ptr<__node, __tree_deleter> __left( - __copy_construct_tree(static_cast<__node_pointer>(__src->__left_)), __node_alloc_); - __node_pointer __right = __copy_construct_tree(static_cast<__node_pointer>(__src->__right_)); + __construct_from_tree(static_cast<__node_pointer>(__src->__left_), __construct), __node_alloc_); + __node_pointer __right = __construct_from_tree(static_cast<__node_pointer>(__src->__right_), __construct); __node_pointer __new_node_ptr = __new_node.release(); @@ -1414,46 +1405,85 @@ private: return __new_node_ptr; } + _LIBCPP_HIDE_FROM_ABI __node_pointer __copy_construct_tree(__node_pointer __src) { + return __construct_from_tree(__src, [this](const value_type& __val) { return __construct_node(__val); }); + } + + template <class _ValueT = _Tp, __enable_if_t<__is_tree_value_type_v<_ValueT>, int> = 0> + _LIBCPP_HIDE_FROM_ABI __node_pointer __move_construct_tree(__node_pointer __src) { + return __construct_from_tree(__src, [this](value_type& __val) { + return __construct_node(const_cast<key_type&&>(__val.first), std::move(__val.second)); + }); + } + + template <class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type_v<_ValueT>, int> = 0> + _LIBCPP_HIDE_FROM_ABI __node_pointer __move_construct_tree(__node_pointer __src) { + return __construct_from_tree(__src, [this](value_type& __val) { return __construct_node(std::move(__val)); }); + } + + template <class _Assignment, class _ConstructionAlg> // This copy assignment will always produce a correct red-black-tree assuming the incoming tree is correct, since our // own tree is a red-black-tree and the incoming tree is a red-black-tree. The invariants of a red-black-tree are // temporarily not met until all of the incoming red-black tree is copied. #ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function _LIBCPP_HIDE_FROM_ABI #endif - __node_pointer - __copy_assign_tree(__node_pointer __dest, __node_pointer __src) { + __node_pointer __assign_from_tree( + __node_pointer __dest, __node_pointer __src, _Assignment __assign, _ConstructionAlg __construct_subtree) { if (!__src) { destroy(__dest); return nullptr; } - __assign_value(__dest->__get_value(), __src->__get_value()); + __assign(__dest->__get_value(), __src->__get_value()); __dest->__is_black_ = __src->__is_black_; // If we already have a left node in the destination tree, reuse it and copy-assign recursively if (__dest->__left_) { - __dest->__left_ = static_cast<__node_base_pointer>(__copy_assign_tree( - static_cast<__node_pointer>(__dest->__left_), static_cast<__node_pointer>(__src->__left_))); + __dest->__left_ = static_cast<__node_base_pointer>(__assign_from_tree( + static_cast<__node_pointer>(__dest->__left_), + static_cast<__node_pointer>(__src->__left_), + __assign, + __construct_subtree)); // Otherwise, we must create new nodes; copy-construct from here on } else if (__src->__left_) { - auto __new_left = __copy_construct_tree(static_cast<__node_pointer>(__src->__left_)); + auto __new_left = __construct_subtree(static_cast<__node_pointer>(__src->__left_)); __dest->__left_ = static_cast<__node_base_pointer>(__new_left); __new_left->__parent_ = static_cast<__end_node_pointer>(__dest); } // Identical to the left case above, just for the right nodes if (__dest->__right_) { - __dest->__right_ = static_cast<__node_base_pointer>(__copy_assign_tree( - static_cast<__node_pointer>(__dest->__right_), static_cast<__node_pointer>(__src->__right_))); + __dest->__right_ = static_cast<__node_base_pointer>(__assign_from_tree( + static_cast<__node_pointer>(__dest->__right_), + static_cast<__node_pointer>(__src->__right_), + __assign, + __construct_subtree)); } else if (__src->__right_) { - auto __new_right = __copy_construct_tree(static_cast<__node_pointer>(__src->__right_)); + auto __new_right = __construct_subtree(static_cast<__node_pointer>(__src->__right_)); __dest->__right_ = static_cast<__node_base_pointer>(__new_right); __new_right->__parent_ = static_cast<__end_node_pointer>(__dest); } return __dest; } + + _LIBCPP_HIDE_FROM_ABI __node_pointer __copy_assign_tree(__node_pointer __dest, __node_pointer __src) { + return __assign_from_tree( + __dest, + __src, + [](value_type& __lhs, const value_type& __rhs) { __assign_value(__lhs, __rhs); }, + [this](__node_pointer __nd) { return __copy_construct_tree(__nd); }); + } + + _LIBCPP_HIDE_FROM_ABI __node_pointer __move_assign_tree(__node_pointer __dest, __node_pointer __src) { + return __assign_from_tree( + __dest, + __src, + [](value_type& __lhs, value_type& __rhs) { __assign_value(__lhs, std::move(__rhs)); }, + [this](__node_pointer __nd) { return __move_construct_tree(__nd); }); + } }; // Precondition: __size_ != 0 @@ -1594,21 +1624,26 @@ __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) _NOEXCEPT_( template <class _Tp, class _Compare, class _Allocator> __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a) - : __node_alloc_(__node_allocator(__a)), __size_(0), __value_comp_(std::move(__t.value_comp())) { + : __begin_node_(__end_node()), + __node_alloc_(__node_allocator(__a)), + __size_(0), + __value_comp_(std::move(__t.value_comp())) { + if (__t.size() == 0) + return; if (__a == __t.__alloc()) { - if (__t.__size_ == 0) - __begin_node_ = __end_node(); - else { - __begin_node_ = __t.__begin_node_; - __end_node()->__left_ = __t.__end_node()->__left_; - __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node()); - __size_ = __t.__size_; - __t.__begin_node_ = __t.__end_node(); - __t.__end_node()->__left_ = nullptr; - __t.__size_ = 0; - } + __begin_node_ = __t.__begin_node_; + __end_node()->__left_ = __t.__end_node()->__left_; + __end_node()->__left_->__parent_ = static_cast<__end_node_pointer>(__end_node()); + __size_ = __t.__size_; + __t.__begin_node_ = __t.__end_node(); + __t.__end_node()->__left_ = nullptr; + __t.__size_ = 0; } else { - __begin_node_ = __end_node(); + *__root_ptr() = static_cast<__node_base_pointer>(__move_construct_tree(__t.__root())); + __root()->__parent_ = __end_node(); + __begin_node_ = static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_)); + __size_ = __t.size(); + __t.clear(); // Ensure that __t is in a valid state after moving out the keys } } @@ -1633,22 +1668,21 @@ void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type) template <class _Tp, class _Compare, class _Allocator> void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) { - if (__node_alloc() == __t.__node_alloc()) + if (__node_alloc() == __t.__node_alloc()) { __move_assign(__t, true_type()); - else { - value_comp() = std::move(__t.value_comp()); - const_iterator __e = end(); + } else { + value_comp() = std::move(__t.value_comp()); if (__size_ != 0) { - _DetachedTreeCache __cache(this); - while (__cache.__get() != nullptr && __t.__size_ != 0) { - __assign_value(__cache.__get()->__get_value(), std::move(__t.remove(__t.begin())->__get_value())); - __node_insert_multi(__cache.__get()); - __cache.__advance(); - } - } - while (__t.__size_ != 0) { - __insert_multi_from_orphaned_node(__e, std::move(__t.remove(__t.begin())->__get_value())); + *__root_ptr() = static_cast<__node_base_pointer>(__move_assign_tree(__root(), __t.__root())); + } else { + *__root_ptr() = static_cast<__node_base_pointer>(__move_construct_tree(__t.__root())); + if (__root()) + __root()->__parent_ = __end_node(); } + __begin_node_ = + __end_node()->__left_ ? static_cast<__end_node_pointer>(std::__tree_min(__end_node()->__left_)) : __end_node(); + __size_ = __t.size(); + __t.clear(); // Ensure that __t is in a valid state after moving out the keys } } diff --git a/libcxx/include/__type_traits/aligned_storage.h b/libcxx/include/__type_traits/aligned_storage.h index 5c2208a..33c0368 100644 --- a/libcxx/include/__type_traits/aligned_storage.h +++ b/libcxx/include/__type_traits/aligned_storage.h @@ -11,8 +11,6 @@ #include <__config> #include <__cstddef/size_t.h> -#include <__type_traits/integral_constant.h> -#include <__type_traits/type_list.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -21,10 +19,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _Tp> -struct __align_type { - static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp); - typedef _Tp type; -}; +struct _ALIGNAS(_LIBCPP_PREFERRED_ALIGNOF(_Tp)) _AlignedAsT {}; + +template <class... _Args> +struct __max_align_impl : _AlignedAsT<_Args>... {}; struct __struct_double { long double __lx; @@ -33,41 +31,16 @@ struct __struct_double4 { double __lx[4]; }; -using __all_types _LIBCPP_NODEBUG = - __type_list<__align_type<unsigned char>, - __align_type<unsigned short>, - __align_type<unsigned int>, - __align_type<unsigned long>, - __align_type<unsigned long long>, - __align_type<double>, - __align_type<long double>, - __align_type<__struct_double>, - __align_type<__struct_double4>, - __align_type<int*> >; - -template <class _TL, size_t _Len> -struct __find_max_align; - -template <class _Head, size_t _Len> -struct __find_max_align<__type_list<_Head>, _Len> : public integral_constant<size_t, _Head::value> {}; - -template <size_t _Len, size_t _A1, size_t _A2> -struct __select_align { -private: - static const size_t __min = _A2 < _A1 ? _A2 : _A1; - static const size_t __max = _A1 < _A2 ? _A2 : _A1; - -public: - static const size_t value = _Len < __max ? __min : __max; -}; +inline const size_t __aligned_storage_max_align = + _LIBCPP_ALIGNOF(__max_align_impl<unsigned long long, double, long double, __struct_double, __struct_double4, int*>); -template <class _Head, class... _Tail, size_t _Len> -struct __find_max_align<__type_list<_Head, _Tail...>, _Len> - : public integral_constant< - size_t, - __select_align<_Len, _Head::value, __find_max_align<__type_list<_Tail...>, _Len>::value>::value> {}; +template <size_t _Len> +inline const size_t __aligned_storage_alignment = + _Len > __aligned_storage_max_align + ? __aligned_storage_max_align + : size_t(1) << ((sizeof(size_t) * __CHAR_BIT__) - __builtin_clzg(_Len) - 1); -template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value> +template <size_t _Len, size_t _Align = __aligned_storage_alignment<_Len> > struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_NO_SPECIALIZATIONS aligned_storage { union _ALIGNAS(_Align) type { unsigned char __data[(_Len + _Align - 1) / _Align * _Align]; @@ -77,7 +50,7 @@ struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_NO_SPECIALIZATIONS aligned_storage { #if _LIBCPP_STD_VER >= 14 _LIBCPP_SUPPRESS_DEPRECATED_PUSH -template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value> +template <size_t _Len, size_t _Align = __aligned_storage_alignment<_Len> > using aligned_storage_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_storage<_Len, _Align>::type; _LIBCPP_SUPPRESS_DEPRECATED_POP diff --git a/libcxx/include/__type_traits/is_array.h b/libcxx/include/__type_traits/is_array.h index e734d1a..62dd378 100644 --- a/libcxx/include/__type_traits/is_array.h +++ b/libcxx/include/__type_traits/is_array.h @@ -26,6 +26,32 @@ template <class _Tp> _LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_array_v = __is_array(_Tp); #endif +template <class _Tp> +inline const bool __is_bounded_array_v = __is_bounded_array(_Tp); + +#if _LIBCPP_STD_VER >= 20 + +template <class _Tp> +struct _LIBCPP_NO_SPECIALIZATIONS is_bounded_array : bool_constant<__is_bounded_array(_Tp)> {}; + +template <class _Tp> +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_bounded_array_v = __is_bounded_array(_Tp); + +#endif + +template <class _Tp> +inline const bool __is_unbounded_array_v = __is_unbounded_array(_Tp); + +#if _LIBCPP_STD_VER >= 20 + +template <class _Tp> +struct _LIBCPP_NO_SPECIALIZATIONS is_unbounded_array : bool_constant<__is_unbounded_array(_Tp)> {}; + +template <class _Tp> +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_unbounded_array_v = __is_unbounded_array(_Tp); + +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___TYPE_TRAITS_IS_ARRAY_H diff --git a/libcxx/include/__type_traits/is_bounded_array.h b/libcxx/include/__type_traits/is_bounded_array.h deleted file mode 100644 index 8a41e07..0000000 --- a/libcxx/include/__type_traits/is_bounded_array.h +++ /dev/null @@ -1,36 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___TYPE_TRAITS_IS_BOUNDED_ARRAY_H -#define _LIBCPP___TYPE_TRAITS_IS_BOUNDED_ARRAY_H - -#include <__config> -#include <__type_traits/integral_constant.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -template <class _Tp> -inline const bool __is_bounded_array_v = __is_bounded_array(_Tp); - -#if _LIBCPP_STD_VER >= 20 - -template <class _Tp> -struct _LIBCPP_NO_SPECIALIZATIONS is_bounded_array : bool_constant<__is_bounded_array(_Tp)> {}; - -template <class _Tp> -_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_bounded_array_v = __is_bounded_array(_Tp); - -#endif - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___TYPE_TRAITS_IS_BOUNDED_ARRAY_H diff --git a/libcxx/include/__type_traits/is_floating_point.h b/libcxx/include/__type_traits/is_floating_point.h index b87363f..586fce6 100644 --- a/libcxx/include/__type_traits/is_floating_point.h +++ b/libcxx/include/__type_traits/is_floating_point.h @@ -20,18 +20,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD // clang-format off -template <class _Tp> struct __libcpp_is_floating_point : false_type {}; -template <> struct __libcpp_is_floating_point<float> : true_type {}; -template <> struct __libcpp_is_floating_point<double> : true_type {}; -template <> struct __libcpp_is_floating_point<long double> : true_type {}; +template <class _Tp> inline const bool __is_floating_point_impl = false; +template <> inline const bool __is_floating_point_impl<float> = true; +template <> inline const bool __is_floating_point_impl<double> = true; +template <> inline const bool __is_floating_point_impl<long double> = true; // clang-format on template <class _Tp> -struct _LIBCPP_NO_SPECIALIZATIONS is_floating_point : __libcpp_is_floating_point<__remove_cv_t<_Tp> > {}; +struct _LIBCPP_NO_SPECIALIZATIONS is_floating_point + : integral_constant<bool, __is_floating_point_impl<__remove_cv_t<_Tp> > > {}; #if _LIBCPP_STD_VER >= 17 template <class _Tp> -_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value; +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_floating_point_v = __is_floating_point_impl<__remove_cv_t<_Tp>>; #endif _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__type_traits/is_replaceable.h b/libcxx/include/__type_traits/is_replaceable.h deleted file mode 100644 index e1d17c0..0000000 --- a/libcxx/include/__type_traits/is_replaceable.h +++ /dev/null @@ -1,61 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___TYPE_TRAITS_IS_REPLACEABLE_H -#define _LIBCPP___TYPE_TRAITS_IS_REPLACEABLE_H - -#include <__config> -#include <__type_traits/enable_if.h> -#include <__type_traits/integral_constant.h> -#include <__type_traits/is_same.h> -#include <__type_traits/is_trivially_copyable.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -// A type is replaceable if, with `x` and `y` being different objects, `x = std::move(y)` is equivalent to: -// -// std::destroy_at(&x) -// std::construct_at(&x, std::move(y)) -// -// This allows turning a move-assignment into a sequence of destroy + move-construct, which -// is often more efficient. This is especially relevant when the move-construct is in fact -// part of a trivial relocation from somewhere else, in which case there is a huge win. -// -// Note that this requires language support in order to be really effective, but we -// currently emulate the base template with something very conservative. -template <class _Tp, class = void> -struct __is_replaceable : is_trivially_copyable<_Tp> {}; - -template <class _Tp> -struct __is_replaceable<_Tp, __enable_if_t<is_same<_Tp, typename _Tp::__replaceable>::value> > : true_type {}; - -template <class _Tp> -inline const bool __is_replaceable_v = __is_replaceable<_Tp>::value; - -// Determines whether an allocator member of a container is replaceable. -// -// First, we require the allocator type to be considered replaceable. If not, then something fishy might be -// happening. Assuming the allocator type is replaceable, we conclude replaceability of the allocator as a -// member of the container if the allocator always compares equal (in which case propagation doesn't matter), -// or if the allocator always propagates on assignment, which is required in order for move construction and -// assignment to be equivalent. -template <class _AllocatorTraits> -struct __container_allocator_is_replaceable - : integral_constant<bool, - __is_replaceable_v<typename _AllocatorTraits::allocator_type> && - (_AllocatorTraits::is_always_equal::value || - (_AllocatorTraits::propagate_on_container_move_assignment::value && - _AllocatorTraits::propagate_on_container_copy_assignment::value))> {}; - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___TYPE_TRAITS_IS_REPLACEABLE_H diff --git a/libcxx/include/__type_traits/is_unbounded_array.h b/libcxx/include/__type_traits/is_unbounded_array.h deleted file mode 100644 index e14809e..0000000 --- a/libcxx/include/__type_traits/is_unbounded_array.h +++ /dev/null @@ -1,38 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___TYPE_TRAITS_IS_UNBOUNDED_ARRAY_H -#define _LIBCPP___TYPE_TRAITS_IS_UNBOUNDED_ARRAY_H - -#include <__config> -#include <__type_traits/integral_constant.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -template <class> -inline const bool __is_unbounded_array_v = false; -template <class _Tp> -inline const bool __is_unbounded_array_v<_Tp[]> = true; - -#if _LIBCPP_STD_VER >= 20 - -template <class _Tp> -struct _LIBCPP_NO_SPECIALIZATIONS is_unbounded_array : bool_constant<__is_unbounded_array_v<_Tp>> {}; - -template <class _Tp> -_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_unbounded_array_v = __is_unbounded_array_v<_Tp>; - -#endif - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___TYPE_TRAITS_IS_UNBOUNDED_ARRAY_H diff --git a/libcxx/include/__utility/cmp.h b/libcxx/include/__utility/cmp.h index 68864e2..7cfe640 100644 --- a/libcxx/include/__utility/cmp.h +++ b/libcxx/include/__utility/cmp.h @@ -31,7 +31,7 @@ concept __comparison_can_promote_to = sizeof(_Tp) < sizeof(_Ip) || (sizeof(_Tp) == sizeof(_Ip) && __signed_integer<_Tp>); template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up> -_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept { if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>) return __t == __u; else if constexpr (__comparison_can_promote_to<_Tp, int> && __comparison_can_promote_to<_Up, int>) @@ -45,12 +45,12 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept { } template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up> -_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_not_equal(_Tp __t, _Up __u) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_not_equal(_Tp __t, _Up __u) noexcept { return !std::cmp_equal(__t, __u); } template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up> -_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept { if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>) return __t < __u; else if constexpr (__comparison_can_promote_to<_Tp, int> && __comparison_can_promote_to<_Up, int>) @@ -64,22 +64,22 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept { } template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up> -_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater(_Tp __t, _Up __u) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater(_Tp __t, _Up __u) noexcept { return std::cmp_less(__u, __t); } template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up> -_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less_equal(_Tp __t, _Up __u) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less_equal(_Tp __t, _Up __u) noexcept { return !std::cmp_greater(__t, __u); } template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up> -_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater_equal(_Tp __t, _Up __u) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater_equal(_Tp __t, _Up __u) noexcept { return !std::cmp_less(__t, __u); } template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up> -_LIBCPP_HIDE_FROM_ABI constexpr bool in_range(_Up __u) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool in_range(_Up __u) noexcept { return std::cmp_less_equal(__u, numeric_limits<_Tp>::max()) && std::cmp_greater_equal(__u, numeric_limits<_Tp>::min()); } diff --git a/libcxx/include/__utility/integer_sequence.h b/libcxx/include/__utility/integer_sequence.h index 329826a..9450d52 100644 --- a/libcxx/include/__utility/integer_sequence.h +++ b/libcxx/include/__utility/integer_sequence.h @@ -33,7 +33,7 @@ template <class _Tp, _Tp... _Indices> struct __integer_sequence { using value_type = _Tp; static_assert(is_integral<_Tp>::value, "std::integer_sequence can only be instantiated with an integral type"); - static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return sizeof...(_Indices); } + [[__nodiscard__]] static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return sizeof...(_Indices); } }; template <size_t... _Indices> @@ -42,6 +42,9 @@ using __index_sequence _LIBCPP_NODEBUG = __integer_sequence<size_t, _Indices...> template <size_t _SequenceSize> using __make_index_sequence _LIBCPP_NODEBUG = __make_integer_sequence_impl<__integer_sequence, size_t, _SequenceSize>; +template <class... _Args> +using __index_sequence_for _LIBCPP_NODEBUG = __make_index_sequence<sizeof...(_Args)>; + # if _LIBCPP_STD_VER >= 14 template <class _Tp, _Tp... _Indices> diff --git a/libcxx/include/__utility/pair.h b/libcxx/include/__utility/pair.h index 33694c52..d3914f6 100644 --- a/libcxx/include/__utility/pair.h +++ b/libcxx/include/__utility/pair.h @@ -31,8 +31,6 @@ #include <__type_traits/is_implicitly_default_constructible.h> #include <__type_traits/is_nothrow_assignable.h> #include <__type_traits/is_nothrow_constructible.h> -#include <__type_traits/is_replaceable.h> -#include <__type_traits/is_same.h> #include <__type_traits/is_swappable.h> #include <__type_traits/is_trivially_relocatable.h> #include <__type_traits/nat.h> @@ -102,7 +100,6 @@ struct pair __conditional_t<__libcpp_is_trivially_relocatable<_T1>::value && __libcpp_is_trivially_relocatable<_T2>::value, pair, void>; - using __replaceable _LIBCPP_NODEBUG = __conditional_t<__is_replaceable_v<_T1> && __is_replaceable_v<_T2>, pair, void>; _LIBCPP_HIDE_FROM_ABI pair(pair const&) = default; _LIBCPP_HIDE_FROM_ABI pair(pair&&) = default; @@ -222,11 +219,7 @@ struct pair _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, tuple<_Args2...> __second_args) noexcept( is_nothrow_constructible<first_type, _Args1...>::value && is_nothrow_constructible<second_type, _Args2...>::value) - : pair(__pc, - __first_args, - __second_args, - __make_index_sequence<sizeof...(_Args1)>(), - __make_index_sequence<sizeof...(_Args2)>()) {} + : pair(__pc, __first_args, __second_args, __index_sequence_for<_Args1...>(), __index_sequence_for<_Args2...>()) {} _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(__conditional_t<is_copy_assignable<first_type>::value && is_copy_assignable<second_type>::value, diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h index 316d3a9..4961a5f 100644 --- a/libcxx/include/__vector/vector.h +++ b/libcxx/include/__vector/vector.h @@ -12,11 +12,11 @@ #include <__algorithm/copy.h> #include <__algorithm/copy_n.h> #include <__algorithm/fill_n.h> +#include <__algorithm/iterator_operations.h> #include <__algorithm/max.h> #include <__algorithm/min.h> #include <__algorithm/move.h> #include <__algorithm/move_backward.h> -#include <__algorithm/ranges_copy_n.h> #include <__algorithm/rotate.h> #include <__assert> #include <__config> @@ -54,7 +54,6 @@ #include <__type_traits/is_nothrow_assignable.h> #include <__type_traits/is_nothrow_constructible.h> #include <__type_traits/is_pointer.h> -#include <__type_traits/is_replaceable.h> #include <__type_traits/is_same.h> #include <__type_traits/is_trivially_relocatable.h> #include <__type_traits/type_identity.h> @@ -123,10 +122,6 @@ public: __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<allocator_type>::value, vector, void>; - using __replaceable _LIBCPP_NODEBUG = - __conditional_t<__is_replaceable_v<pointer> && __container_allocator_is_replaceable<__alloc_traits>::value, - vector, - void>; static_assert(__check_valid_allocator<allocator_type>::value, ""); static_assert(is_same<typename allocator_type::value_type, value_type>::value, @@ -319,7 +314,7 @@ public: is_constructible<value_type, typename iterator_traits<_ForwardIterator>::reference>::value, int> = 0> _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(_ForwardIterator __first, _ForwardIterator __last) { - __assign_with_size(__first, __last, std::distance(__first, __last)); + __assign_with_size<_ClassicAlgPolicy>(__first, __last, std::distance(__first, __last)); } #if _LIBCPP_STD_VER >= 23 @@ -327,7 +322,7 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr void assign_range(_Range&& __range) { if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { auto __n = static_cast<size_type>(ranges::distance(__range)); - __assign_with_size(ranges::begin(__range), ranges::end(__range), __n); + __assign_with_size<_RangeAlgPolicy>(ranges::begin(__range), ranges::end(__range), __n); } else { __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); @@ -523,7 +518,7 @@ public: int> = 0> _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) { - return __insert_with_size(__position, __first, __last, std::distance(__first, __last)); + return __insert_with_size<_ClassicAlgPolicy>(__position, __first, __last, std::distance(__first, __last)); } #if _LIBCPP_STD_VER >= 23 @@ -531,7 +526,7 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr iterator insert_range(const_iterator __position, _Range&& __range) { if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { auto __n = static_cast<size_type>(ranges::distance(__range)); - return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n); + return __insert_with_size<_RangeAlgPolicy>(__position, ranges::begin(__range), ranges::end(__range), __n); } else { return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); @@ -624,12 +619,13 @@ private: // The `_Iterator` in `*_with_size` functions can be input-only only if called from `*_range` (since C++23). // Otherwise, `_Iterator` is a forward iterator. - template <class _Iterator, class _Sentinel> + template <class _AlgPolicy, class _Iterator, class _Sentinel> _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __assign_with_size(_Iterator __first, _Sentinel __last, difference_type __n); - template <class _Iterator, - __enable_if_t<!is_same<decltype(*std::declval<_Iterator&>())&&, value_type&&>::value, int> = 0> + template <class _AlgPolicy, + class _Iterator, + __enable_if_t<!is_same<__policy_value_type<_AlgPolicy, _Iterator>, value_type>::value, int> = 0> _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __insert_assign_n_unchecked(_Iterator __first, difference_type __n, pointer __position) { for (pointer __end_position = __position + __n; __position != __end_position; ++__position, (void)++__first) { @@ -638,25 +634,19 @@ private: } } - template <class _Iterator, - __enable_if_t<is_same<decltype(*std::declval<_Iterator&>())&&, value_type&&>::value, int> = 0> + template <class _AlgPolicy, + class _Iterator, + __enable_if_t<is_same<__policy_value_type<_AlgPolicy, _Iterator>, value_type>::value, int> = 0> _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __insert_assign_n_unchecked(_Iterator __first, difference_type __n, pointer __position) { -#if _LIBCPP_STD_VER >= 23 - if constexpr (!forward_iterator<_Iterator>) { // Handles input-only sized ranges for insert_range - ranges::copy_n(std::move(__first), __n, __position); - } else -#endif - { - std::copy_n(__first, __n, __position); - } + std::__copy_n<_AlgPolicy>(std::move(__first), __n, __position); } template <class _InputIterator, class _Sentinel> _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator __insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last); - template <class _Iterator, class _Sentinel> + template <class _AlgPolicy, class _Iterator, class _Sentinel> _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator __insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n); @@ -664,9 +654,6 @@ private: _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n); - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n); - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const_reference __x); - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator __make_iter(pointer __p) _NOEXCEPT { #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR // Bound the iterator according to the capacity, rather than the size. @@ -971,36 +958,6 @@ vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __ __tx.__pos_ = std::__uninitialized_allocator_copy(this->__alloc_, std::move(__first), std::move(__last), __tx.__pos_); } -// Default constructs __n objects starting at __end_ -// throws if construction throws -// Postcondition: size() == size() + __n -// Exception safety: strong. -template <class _Tp, class _Allocator> -_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__append(size_type __n) { - if (static_cast<size_type>(this->__cap_ - this->__end_) >= __n) - this->__construct_at_end(__n); - else { - __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), size(), this->__alloc_); - __v.__construct_at_end(__n); - __swap_out_circular_buffer(__v); - } -} - -// Default constructs __n objects starting at __end_ -// throws if construction throws -// Postcondition: size() == size() + __n -// Exception safety: strong. -template <class _Tp, class _Allocator> -_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__append(size_type __n, const_reference __x) { - if (static_cast<size_type>(this->__cap_ - this->__end_) >= __n) - this->__construct_at_end(__n, __x); - else { - __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), size(), this->__alloc_); - __v.__construct_at_end(__n, __x); - __swap_out_circular_buffer(__v); - } -} - template <class _Tp, class _Allocator> _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI vector<_Tp, _Allocator>::vector(vector&& __x) #if _LIBCPP_STD_VER >= 17 @@ -1077,20 +1034,14 @@ vector<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __l } template <class _Tp, class _Allocator> -template <class _Iterator, class _Sentinel> +template <class _AlgPolicy, class _Iterator, class _Sentinel> _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last, difference_type __n) { size_type __new_size = static_cast<size_type>(__n); if (__new_size <= capacity()) { if (__new_size > size()) { -#if _LIBCPP_STD_VER >= 23 - auto __mid = ranges::copy_n(std::move(__first), size(), this->__begin_).in; + auto __mid = std::__copy_n<_AlgPolicy>(std::move(__first), size(), this->__begin_).first; __construct_at_end(std::move(__mid), std::move(__last), __new_size - size()); -#else - _Iterator __mid = std::next(__first, size()); - std::copy(__first, __mid, this->__begin_); - __construct_at_end(__mid, __last, __new_size - size()); -#endif } else { pointer __m = std::__copy(std::move(__first), __last, this->__begin_).second; this->__destruct_at_end(__m); @@ -1364,7 +1315,7 @@ vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position, _Inpu } template <class _Tp, class _Allocator> -template <class _Iterator, class _Sentinel> +template <class _AlgPolicy, class _Iterator, class _Sentinel> _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::__insert_with_size( const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n) { @@ -1385,12 +1336,12 @@ vector<_Tp, _Allocator>::__insert_with_size( __construct_at_end(__m, __last, __n - __dx); if (__dx > 0) { __move_range(__p, __old_last, __p + __n); - __insert_assign_n_unchecked(__first, __dx, __p); + __insert_assign_n_unchecked<_AlgPolicy>(__first, __dx, __p); } } } else { __move_range(__p, __old_last, __p + __n); - __insert_assign_n_unchecked(std::move(__first), __n, __p); + __insert_assign_n_unchecked<_AlgPolicy>(std::move(__first), __n, __p); } } else { __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, this->__alloc_); @@ -1402,21 +1353,35 @@ vector<_Tp, _Allocator>::__insert_with_size( } template <class _Tp, class _Allocator> -_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __sz) { - size_type __cs = size(); - if (__cs < __sz) - this->__append(__sz - __cs); - else if (__cs > __sz) - this->__destruct_at_end(this->__begin_ + __sz); +_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __new_size) { + size_type __current_size = size(); + if (__current_size < __new_size) { + if (__new_size <= capacity()) { + __construct_at_end(__new_size - __current_size); + } else { + __split_buffer<value_type, allocator_type&> __v(__recommend(__new_size), __current_size, __alloc_); + __v.__construct_at_end(__new_size - __current_size); + __swap_out_circular_buffer(__v); + } + } else if (__current_size > __new_size) { + this->__destruct_at_end(this->__begin_ + __new_size); + } } template <class _Tp, class _Allocator> -_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __sz, const_reference __x) { - size_type __cs = size(); - if (__cs < __sz) - this->__append(__sz - __cs, __x); - else if (__cs > __sz) - this->__destruct_at_end(this->__begin_ + __sz); +_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __new_size, const_reference __x) { + size_type __current_size = size(); + if (__current_size < __new_size) { + if (__new_size <= capacity()) + __construct_at_end(__new_size - __current_size, __x); + else { + __split_buffer<value_type, allocator_type&> __v(__recommend(__new_size), __current_size, __alloc_); + __v.__construct_at_end(__new_size - __current_size, __x); + __swap_out_circular_buffer(__v); + } + } else if (__current_size > __new_size) { + this->__destruct_at_end(this->__begin_ + __new_size); + } } template <class _Tp, class _Allocator> diff --git a/libcxx/include/any b/libcxx/include/any index 148fb16..5c779e3 100644 --- a/libcxx/include/any +++ b/libcxx/include/any @@ -88,7 +88,6 @@ namespace std { # include <__new/allocate.h> # include <__type_traits/add_cv_quals.h> # include <__type_traits/add_pointer.h> -# include <__type_traits/aligned_storage.h> # include <__type_traits/conditional.h> # include <__type_traits/decay.h> # include <__type_traits/enable_if.h> @@ -147,14 +146,13 @@ template <class _ValueType> _LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any*) _NOEXCEPT; namespace __any_imp { -_LIBCPP_SUPPRESS_DEPRECATED_PUSH -using _Buffer _LIBCPP_NODEBUG = aligned_storage_t<3 * sizeof(void*), alignof(void*)>; -_LIBCPP_SUPPRESS_DEPRECATED_POP +inline constexpr size_t __small_buffer_size = 3 * sizeof(void*); +inline constexpr size_t __small_buffer_alignment = alignof(void*); template <class _Tp> using _IsSmallObject _LIBCPP_NODEBUG = integral_constant<bool, - sizeof(_Tp) <= sizeof(_Buffer) && alignof(_Buffer) % alignof(_Tp) == 0 && + sizeof(_Tp) <= __small_buffer_size && alignof(_Tp) <= __small_buffer_alignment && is_nothrow_move_constructible<_Tp>::value >; enum class _Action { _Destroy, _Copy, _Move, _Get, _TypeInfo }; @@ -264,10 +262,10 @@ public: _LIBCPP_HIDE_FROM_ABI void swap(any& __rhs) _NOEXCEPT; // 6.3.4 any observers - _LIBCPP_HIDE_FROM_ABI bool has_value() const _NOEXCEPT { return __h_ != nullptr; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool has_value() const _NOEXCEPT { return __h_ != nullptr; } # if _LIBCPP_HAS_RTTI - _LIBCPP_HIDE_FROM_ABI const type_info& type() const _NOEXCEPT { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const type_info& type() const _NOEXCEPT { if (__h_) { return *static_cast<type_info const*>(this->__call(_Action::_TypeInfo)); } else { @@ -284,7 +282,7 @@ private: union _Storage { _LIBCPP_HIDE_FROM_ABI constexpr _Storage() : __ptr(nullptr) {} void* __ptr; - __any_imp::_Buffer __buf; + alignas(__any_imp::__small_buffer_alignment) char __buf[__any_imp::__small_buffer_size]; }; _LIBCPP_HIDE_FROM_ABI void* @@ -494,17 +492,17 @@ inline _LIBCPP_HIDE_FROM_ABI void any::swap(any& __rhs) _NOEXCEPT { inline _LIBCPP_HIDE_FROM_ABI void swap(any& __lhs, any& __rhs) _NOEXCEPT { __lhs.swap(__rhs); } template <class _Tp, class... _Args> -inline _LIBCPP_HIDE_FROM_ABI any make_any(_Args&&... __args) { +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI any make_any(_Args&&... __args) { return any(in_place_type<_Tp>, std::forward<_Args>(__args)...); } template <class _Tp, class _Up, class... _Args> -inline _LIBCPP_HIDE_FROM_ABI any make_any(initializer_list<_Up> __il, _Args&&... __args) { +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI any make_any(initializer_list<_Up> __il, _Args&&... __args) { return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...); } template <class _ValueType> -inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any const& __v) { +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any const& __v) { using _RawValueType = __remove_cvref_t<_ValueType>; static_assert(is_constructible<_ValueType, _RawValueType const&>::value, "ValueType is required to be a const lvalue reference " @@ -516,7 +514,7 @@ inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any const& __v) { } template <class _ValueType> -inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any& __v) { +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any& __v) { using _RawValueType = __remove_cvref_t<_ValueType>; static_assert(is_constructible<_ValueType, _RawValueType&>::value, "ValueType is required to be an lvalue reference " @@ -528,7 +526,7 @@ inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any& __v) { } template <class _ValueType> -inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any&& __v) { +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any&& __v) { using _RawValueType = __remove_cvref_t<_ValueType>; static_assert(is_constructible<_ValueType, _RawValueType>::value, "ValueType is required to be an rvalue reference " @@ -540,7 +538,7 @@ inline _LIBCPP_HIDE_FROM_ABI _ValueType any_cast(any&& __v) { } template <class _ValueType> -inline _LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const* __any) _NOEXCEPT { +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const* __any) _NOEXCEPT { static_assert(!is_void_v<_ValueType>, "_ValueType may not be void."); static_assert(!is_reference<_ValueType>::value, "_ValueType may not be a reference."); return std::any_cast<_ValueType>(const_cast<any*>(__any)); @@ -557,7 +555,7 @@ inline _LIBCPP_HIDE_FROM_ABI _RetType __pointer_or_func_cast(void*, /*IsFunction } template <class _ValueType> -_LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any* __any) _NOEXCEPT { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any* __any) _NOEXCEPT { using __any_imp::_Action; static_assert(!is_void_v<_ValueType>, "_ValueType may not be void."); static_assert(!is_reference<_ValueType>::value, "_ValueType may not be a reference."); diff --git a/libcxx/include/array b/libcxx/include/array index 9643fc1..0b0c854 100644 --- a/libcxx/include/array +++ b/libcxx/include/array @@ -134,7 +134,6 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce # include <__type_traits/is_const.h> # include <__type_traits/is_constructible.h> # include <__type_traits/is_nothrow_constructible.h> -# include <__type_traits/is_replaceable.h> # include <__type_traits/is_same.h> # include <__type_traits/is_swappable.h> # include <__type_traits/is_trivially_relocatable.h> @@ -176,7 +175,6 @@ template <class _Tp, size_t _Size> struct array { using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, array, void>; - using __replaceable _LIBCPP_NODEBUG = __conditional_t<__is_replaceable_v<_Tp>, array, void>; // types: using __self _LIBCPP_NODEBUG = array; @@ -212,28 +210,28 @@ struct array { } // iterators: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT { # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) return std::__make_static_bounded_iter<_Size>(data(), data()); # else return iterator(data()); # endif } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT { # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) return std::__make_static_bounded_iter<_Size>(data(), data()); # else return const_iterator(data()); # endif } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT { # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) return std::__make_static_bounded_iter<_Size>(data() + _Size, data()); # else return iterator(data() + _Size); # endif } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT { # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) return std::__make_static_bounded_iter<_Size>(data() + _Size, data()); # else @@ -241,62 +239,81 @@ struct array { # endif } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator + rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT { return begin(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT { return end(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT { + return begin(); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT { + return end(); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator + crbegin() const _NOEXCEPT { return rbegin(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT { return rend(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT { + return rend(); + } // capacity: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return _Size; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return _Size; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return _Size; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return _Size; } [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return _Size == 0; } // element access: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type __n) _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type __n) _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>"); return __elems_[__n]; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference operator[](size_type __n) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference + operator[](size_type __n) const _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>"); return __elems_[__n]; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n) { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n) { if (__n >= _Size) std::__throw_out_of_range("array::at"); return __elems_[__n]; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const { if (__n >= _Size) std::__throw_out_of_range("array::at"); return __elems_[__n]; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT { return (*this)[0]; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT { return (*this)[0]; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT { return (*this)[_Size - 1]; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT { + return (*this)[0]; + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT { + return (*this)[0]; + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT { + return (*this)[_Size - 1]; + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT { return (*this)[_Size - 1]; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { return __elems_; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT { return __elems_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { + return __elems_; + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT { + return __elems_; + } }; template <class _Tp> @@ -330,8 +347,10 @@ struct array<_Tp, 0> { }; _ALIGNAS_TYPE(_ArrayInStructT) _EmptyType __elems_[sizeof(_ArrayInStructT)]; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { return nullptr; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT { return nullptr; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { return nullptr; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT { + return nullptr; + } // No explicit construct/copy/destroy for aggregate type _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void fill(const value_type&) { @@ -343,28 +362,28 @@ struct array<_Tp, 0> { } // iterators: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT { # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) return std::__make_static_bounded_iter<0>(data(), data()); # else return iterator(data()); # endif } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT { # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) return std::__make_static_bounded_iter<0>(data(), data()); # else return const_iterator(data()); # endif } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT { # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) return std::__make_static_bounded_iter<0>(data(), data()); # else return iterator(data()); # endif } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT { # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) return std::__make_static_bounded_iter<0>(data(), data()); # else @@ -372,68 +391,77 @@ struct array<_Tp, 0> { # endif } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator + rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT { return begin(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT { return end(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT { + return begin(); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT { + return end(); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator + crbegin() const _NOEXCEPT { return rbegin(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT { return rend(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT { + return rend(); + } // capacity: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return 0; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return 0; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return 0; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return 0; } [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return true; } // element access: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type) _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type) _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array"); __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference operator[](size_type) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference + operator[](size_type) const _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array"); __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type) { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type) { std::__throw_out_of_range("array<T, 0>::at"); __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type) const { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type) const { std::__throw_out_of_range("array<T, 0>::at"); __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array"); __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array"); __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array"); __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array"); __libcpp_unreachable(); } @@ -503,25 +531,29 @@ struct tuple_element<_Ip, array<_Tp, _Size> > { }; template <size_t _Ip, class _Tp, size_t _Size> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp& get(array<_Tp, _Size>& __a) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp& +get(array<_Tp, _Size>& __a) _NOEXCEPT { static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)"); return __a.__elems_[_Ip]; } template <size_t _Ip, class _Tp, size_t _Size> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& get(const array<_Tp, _Size>& __a) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +get(const array<_Tp, _Size>& __a) _NOEXCEPT { static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)"); return __a.__elems_[_Ip]; } template <size_t _Ip, class _Tp, size_t _Size> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&& get(array<_Tp, _Size>&& __a) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&& +get(array<_Tp, _Size>&& __a) _NOEXCEPT { static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)"); return std::move(__a.__elems_[_Ip]); } template <size_t _Ip, class _Tp, size_t _Size> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&& get(const array<_Tp, _Size>&& __a) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&& +get(const array<_Tp, _Size>&& __a) _NOEXCEPT { static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array &&)"); return std::move(__a.__elems_[_Ip]); } @@ -541,7 +573,7 @@ __to_array_rvalue_impl(_Tp (&&__arr)[_Size], index_sequence<_Index...>) { } template <typename _Tp, size_t _Size> -_LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size> +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size> to_array(_Tp (&__arr)[_Size]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) { static_assert(!is_array_v<_Tp>, "[array.creation]/1: to_array does not accept multidimensional arrays."); static_assert(is_constructible_v<_Tp, _Tp&>, "[array.creation]/1: to_array requires copy constructible elements."); @@ -549,7 +581,7 @@ to_array(_Tp (&__arr)[_Size]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) { } template <typename _Tp, size_t _Size> -_LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size> +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size> to_array(_Tp (&&__arr)[_Size]) noexcept(is_nothrow_move_constructible_v<_Tp>) { static_assert(!is_array_v<_Tp>, "[array.creation]/4: to_array does not accept multidimensional arrays."); static_assert(is_move_constructible_v<_Tp>, "[array.creation]/4: to_array requires move constructible elements."); diff --git a/libcxx/include/barrier b/libcxx/include/barrier index 41fbfb3..5f9b471 100644 --- a/libcxx/include/barrier +++ b/libcxx/include/barrier @@ -158,7 +158,9 @@ class barrier { public: using arrival_token = typename __barrier_base<_CompletionF>::arrival_token; - static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept { return __barrier_base<_CompletionF>::max(); } + [[nodiscard]] static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept { + return __barrier_base<_CompletionF>::max(); + } _LIBCPP_HIDE_FROM_ABI explicit barrier(ptrdiff_t __count, _CompletionF __completion = _CompletionF()) : __b_(__count, std::move(__completion)) { diff --git a/libcxx/include/bitset b/libcxx/include/bitset index 3453c2f..271e63b 100644 --- a/libcxx/include/bitset +++ b/libcxx/include/bitset @@ -675,53 +675,62 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& set(size_t __pos, bool __val = true); _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& reset() _NOEXCEPT; _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& reset(size_t __pos); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator~() const _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator~() const _NOEXCEPT; _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& flip() _NOEXCEPT; _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& flip(size_t __pos); // element access: # ifdef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator[](size_t __p) const { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator[](size_t __p) const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p < _Size, "bitset::operator[] index out of bounds"); return __base::__make_ref(__p); } # else - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __const_reference operator[](size_t __p) const { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __const_reference operator[](size_t __p) const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p < _Size, "bitset::operator[] index out of bounds"); return __base::__make_ref(__p); } # endif - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 reference operator[](size_t __p) { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 reference operator[](size_t __p) { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p < _Size, "bitset::operator[] index out of bounds"); return __base::__make_ref(__p); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const { return __base::to_ulong(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const { + return __base::to_ulong(); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const { return __base::to_ullong(); } template <class _CharT, class _Traits, class _Allocator> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, _Allocator> + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, _Allocator> to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const; template <class _CharT, class _Traits> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, allocator<_CharT> > + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, allocator<_CharT> > to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const; template <class _CharT> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> > + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> > to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<char, char_traits<char>, allocator<char> > + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<char, char_traits<char>, allocator<char> > to_string(char __zero = '0', char __one = '1') const; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 size_t count() const _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_t size() const _NOEXCEPT { return _Size; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 size_t count() const _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_t size() const _NOEXCEPT { return _Size; } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator==(const bitset& __rhs) const _NOEXCEPT; # if _LIBCPP_STD_VER <= 17 _LIBCPP_HIDE_FROM_ABI bool operator!=(const bitset& __rhs) const _NOEXCEPT; # endif - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool test(size_t __pos) const; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT { return __base::all(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT { return __base::any(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool none() const _NOEXCEPT { return !any(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator<<(size_t __pos) const _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator>>(size_t __pos) const _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool test(size_t __pos) const; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT { + return __base::all(); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT { + return __base::any(); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool none() const _NOEXCEPT { return !any(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator<<(size_t __pos) const _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator>>(size_t __pos) const _NOEXCEPT; private: template <class _CharT, class _Traits> @@ -919,7 +928,7 @@ bitset<_Size>::operator>>(size_t __pos) const _NOEXCEPT { } template <size_t _Size> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size> +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size> operator&(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT { bitset<_Size> __r = __x; __r &= __y; @@ -927,7 +936,7 @@ operator&(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT { } template <size_t _Size> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size> +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size> operator|(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT { bitset<_Size> __r = __x; __r |= __y; @@ -935,7 +944,7 @@ operator|(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT { } template <size_t _Size> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size> +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size> operator^(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT { bitset<_Size> __r = __x; __r ^= __y; @@ -944,7 +953,9 @@ operator^(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT { template <size_t _Size> struct hash<bitset<_Size> > : public __unary_function<bitset<_Size>, size_t> { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const bitset<_Size>& __bs) const _NOEXCEPT { return __bs.__hash_code(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const bitset<_Size>& __bs) const _NOEXCEPT { + return __bs.__hash_code(); + } }; template <class _CharT, class _Traits, size_t _Size> diff --git a/libcxx/include/ccomplex b/libcxx/include/ccomplex index ee7e088..c1cb039 100644 --- a/libcxx/include/ccomplex +++ b/libcxx/include/ccomplex @@ -26,18 +26,10 @@ # pragma GCC system_header # endif -# if _LIBCPP_STD_VER >= 20 - -using __standard_header_ccomplex - _LIBCPP_DEPRECATED_("removed in C++20. Include <complex> instead.") _LIBCPP_NODEBUG = void; -using __use_standard_header_ccomplex _LIBCPP_NODEBUG = __standard_header_ccomplex; - -# elif _LIBCPP_STD_VER >= 17 - -using __standard_header_ccomplex _LIBCPP_DEPRECATED_("Include <complex> instead.") _LIBCPP_NODEBUG = void; -using __use_standard_header_ccomplex _LIBCPP_NODEBUG = __standard_header_ccomplex; - +# if _LIBCPP_STD_VER >= 17 && !__building_module(std) && _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS +# warning <ccomplex> is deprecated in C++17 and removed in C++20. Include <complex> instead. # endif + #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) #endif // _LIBCPP_CCOMPLEX diff --git a/libcxx/include/ciso646 b/libcxx/include/ciso646 index 3416436..d9eae41 100644 --- a/libcxx/include/ciso646 +++ b/libcxx/include/ciso646 @@ -24,13 +24,10 @@ # pragma GCC system_header # endif -# if _LIBCPP_STD_VER >= 20 - -using __standard_header_ciso646 - _LIBCPP_DEPRECATED_("removed in C++20. Include <version> instead.") _LIBCPP_NODEBUG = void; -using __use_standard_header_ciso646 _LIBCPP_NODEBUG = __standard_header_ciso646; - +# if _LIBCPP_STD_VER >= 20 && !__building_module(std) && _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS +# warning <ciso646> is removed in C++20. Include <version> instead. # endif + #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) #endif // _LIBCPP_CISO646 diff --git a/libcxx/include/cstdalign b/libcxx/include/cstdalign index 7f8dd1e..7aa8cc8 100644 --- a/libcxx/include/cstdalign +++ b/libcxx/include/cstdalign @@ -43,17 +43,10 @@ Macros: # undef __alignof_is_defined # define __alignof_is_defined 1 -# if _LIBCPP_STD_VER >= 20 - -using __standard_header_cstdalign _LIBCPP_DEPRECATED_("removed in C++20.") _LIBCPP_NODEBUG = void; -using __use_standard_header_cstdalign _LIBCPP_NODEBUG = __standard_header_cstdalign; - -# elif _LIBCPP_STD_VER >= 17 - -using __standard_header_cstdalign _LIBCPP_DEPRECATED _LIBCPP_NODEBUG = void; -using __use_standard_header_cstdalign _LIBCPP_NODEBUG = __standard_header_cstdalign; - +# if _LIBCPP_STD_VER >= 17 && !__building_module(std) && _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS +# warning <cstdalign> is deprecated in C++17 and removed in C++20. # endif + #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) #endif // _LIBCPP_CSTDALIGN diff --git a/libcxx/include/cstdbool b/libcxx/include/cstdbool index a432d5f..805a287 100644 --- a/libcxx/include/cstdbool +++ b/libcxx/include/cstdbool @@ -31,17 +31,10 @@ Macros: # undef __bool_true_false_are_defined # define __bool_true_false_are_defined 1 -# if _LIBCPP_STD_VER >= 20 - -using __standard_header_cstdbool _LIBCPP_DEPRECATED_("removed in C++20.") _LIBCPP_NODEBUG = void; -using __use_standard_header_cstdbool _LIBCPP_NODEBUG = __standard_header_cstdbool; - -# elif _LIBCPP_STD_VER >= 17 - -using __standard_header_cstdbool _LIBCPP_DEPRECATED _LIBCPP_NODEBUG = void; -using __use_standard_header_cstdbool _LIBCPP_NODEBUG = __standard_header_cstdbool; - +# if _LIBCPP_STD_VER >= 17 && !__building_module(std) && _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS +# warning <cstdbool> is deprecated in C++17 and removed in C++20. # endif + #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) #endif // _LIBCPP_CSTDBOOL diff --git a/libcxx/include/ctgmath b/libcxx/include/ctgmath index db0786f..13b7a96 100644 --- a/libcxx/include/ctgmath +++ b/libcxx/include/ctgmath @@ -28,17 +28,8 @@ # pragma GCC system_header # endif -# if _LIBCPP_STD_VER >= 20 - -using __standard_header_ctgmath - _LIBCPP_DEPRECATED_("removed in C++20. Include <cmath> and <complex> instead.") _LIBCPP_NODEBUG = void; -using __use_standard_header_ctgmath _LIBCPP_NODEBUG = __standard_header_ctgmath; - -# elif _LIBCPP_STD_VER >= 17 - -using __standard_header_ctgmath _LIBCPP_DEPRECATED_("Include <cmath> and <complex> instead.") _LIBCPP_NODEBUG = void; -using __use_standard_header_ctgmath _LIBCPP_NODEBUG = __standard_header_ctgmath; - +# if _LIBCPP_STD_VER >= 17 && !__building_module(std) && _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS +# warning <ctgmath> is deprecated in C++17 and removed in C++20. Include <cmath> and <complex> instead. # endif #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) diff --git a/libcxx/include/deque b/libcxx/include/deque index cbf4b98..ad2d759 100644 --- a/libcxx/include/deque +++ b/libcxx/include/deque @@ -227,7 +227,6 @@ template <class T, class Allocator, class Predicate> # include <__type_traits/is_convertible.h> # include <__type_traits/is_nothrow_assignable.h> # include <__type_traits/is_nothrow_constructible.h> -# include <__type_traits/is_replaceable.h> # include <__type_traits/is_same.h> # include <__type_traits/is_swappable.h> # include <__type_traits/is_trivially_relocatable.h> @@ -531,10 +530,6 @@ public: __libcpp_is_trivially_relocatable<__map>::value && __libcpp_is_trivially_relocatable<allocator_type>::value, deque, void>; - using __replaceable _LIBCPP_NODEBUG = - __conditional_t<__is_replaceable_v<__map> && __container_allocator_is_replaceable<__alloc_traits>::value, - deque, - void>; static_assert(is_nothrow_default_constructible<allocator_type>::value == is_nothrow_default_constructible<__pointer_allocator>::value, @@ -720,45 +715,53 @@ public: // iterators: - _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { __map_pointer __mp = __map_.begin() + __start_ / __block_size; return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); } - _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size); return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size); } - _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { size_type __p = size() + __start_; __map_pointer __mp = __map_.begin() + __p / __block_size; return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); } - _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { size_type __p = size() + __start_; __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size); return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size); } - _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { + return const_reverse_iterator(end()); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { + return const_reverse_iterator(begin()); + } - _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); } - _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); } - _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(begin()); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { + return const_reverse_iterator(end()); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { + return const_reverse_iterator(begin()); + } // capacity: - _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size(); } _LIBCPP_HIDE_FROM_ABI size_type& __size() _NOEXCEPT { return __size_; } _LIBCPP_HIDE_FROM_ABI const size_type& __size() const _NOEXCEPT { return __size_; } - _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return std::min<size_type>(__alloc_traits::max_size(__alloc()), numeric_limits<difference_type>::max()); } _LIBCPP_HIDE_FROM_ABI void resize(size_type __n); @@ -767,14 +770,14 @@ public: [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return size() == 0; } // element access: - _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __i) _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __i) const _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI reference at(size_type __i); - _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __i) const; - _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __i) _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __i) const _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference at(size_type __i); + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __i) const; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT; // 23.2.2.3 modifiers: _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v); diff --git a/libcxx/include/ext/hash_map b/libcxx/include/ext/hash_map index 01ca749..09c9811 100644 --- a/libcxx/include/ext/hash_map +++ b/libcxx/include/ext/hash_map @@ -570,10 +570,7 @@ hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( } template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(const hash_map& __u) : __table_(__u.__table_) { - __table_.__rehash_unique(__u.bucket_count()); - insert(__u.begin(), __u.end()); -} +hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(const hash_map& __u) : __table_(__u.__table_) {} template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder diff --git a/libcxx/include/ext/hash_set b/libcxx/include/ext/hash_set index 2796774..56aa4d8 100644 --- a/libcxx/include/ext/hash_set +++ b/libcxx/include/ext/hash_set @@ -356,10 +356,7 @@ hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set( } template <class _Value, class _Hash, class _Pred, class _Alloc> -hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(const hash_set& __u) : __table_(__u.__table_) { - __table_.__rehash_unique(__u.bucket_count()); - insert(__u.begin(), __u.end()); -} +hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(const hash_set& __u) : __table_(__u.__table_) {} template <class _Value, class _Hash, class _Pred, class _Alloc> template <class _InputIterator> diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list index 272e52d..56c45d0 100644 --- a/libcxx/include/forward_list +++ b/libcxx/include/forward_list @@ -732,50 +732,52 @@ public: _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v); - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return allocator_type(this->__alloc_); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return iterator(__base::__before_begin()->__next_); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return const_iterator(__base::__before_begin()->__next_); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return iterator(nullptr); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { + return iterator(nullptr); + } + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return const_iterator(nullptr); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return const_iterator(__base::__before_begin()->__next_); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return const_iterator(nullptr); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator before_begin() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator before_begin() _NOEXCEPT { return iterator(__base::__before_begin()); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator before_begin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator before_begin() const _NOEXCEPT { return const_iterator(__base::__before_begin()); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbefore_begin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbefore_begin() const _NOEXCEPT { return const_iterator(__base::__before_begin()); } [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __base::__before_begin()->__next_ == nullptr; } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return std::min<size_type>(__node_traits::max_size(this->__alloc_), numeric_limits<difference_type>::max()); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference front() { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference front() { _LIBCPP_ASSERT_NON_NULL(!empty(), "forward_list::front called on an empty list"); return __base::__before_begin()->__next_->__get_value(); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference front() const { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference front() const { _LIBCPP_ASSERT_NON_NULL(!empty(), "forward_list::front called on an empty list"); return __base::__before_begin()->__next_->__get_value(); } diff --git a/libcxx/include/fstream b/libcxx/include/fstream index b07ca63..fbe579a 100644 --- a/libcxx/include/fstream +++ b/libcxx/include/fstream @@ -308,19 +308,6 @@ protected: return basic_streambuf<_CharT, _Traits>::xsputn(__str, __len); } - _LIBCPP_HIDE_FROM_ABI_VIRTUAL streamsize xsgetn(char_type* __str, streamsize __len) override { - if (__always_noconv_) { - const streamsize __n = std::min(this->egptr() - this->gptr(), __len); - if (__n != 0) { - traits_type::copy(__str, this->gptr(), __n); - this->__gbump_ptrdiff(__n); - } - if (__len - __n >= this->egptr() - this->eback()) - return std::fread(__str + __n, sizeof(char_type), __len - __n, __file_); - } - return basic_streambuf<_CharT, _Traits>::xsgetn(__str, __len); - } - private: char* __extbuf_; const char* __extbufnext_; @@ -999,7 +986,7 @@ template <class _CharT, class _Traits> int basic_filebuf<_CharT, _Traits>::__fseek(FILE* __file, pos_type __offset, int __whence) { # if defined(_LIBCPP_MSVCRT_LIKE) return _fseeki64(__file, __offset, __whence); -# elif defined(_NEWLIB_VERSION) +# elif _LIBCPP_LIBC_NEWLIB return fseek(__file, __offset, __whence); # else return ::fseeko(__file, __offset, __whence); @@ -1010,7 +997,7 @@ template <class _CharT, class _Traits> typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>::__ftell(FILE* __file) { # if defined(_LIBCPP_MSVCRT_LIKE) return _ftelli64(__file); -# elif defined(_NEWLIB_VERSION) +# elif _LIBCPP_LIBC_NEWLIB return ftell(__file); # else return ftello(__file); diff --git a/libcxx/include/future b/libcxx/include/future index 4b7c098..c249bc5 100644 --- a/libcxx/include/future +++ b/libcxx/include/future @@ -584,12 +584,9 @@ inline future_status __assoc_sub_state::wait_for(const chrono::duration<_Rep, _P template <class _Rp> class _LIBCPP_HIDDEN __assoc_state : public __assoc_sub_state { typedef __assoc_sub_state base; - _LIBCPP_SUPPRESS_DEPRECATED_PUSH - typedef typename aligned_storage<sizeof(_Rp), _LIBCPP_ALIGNOF(_Rp)>::type _Up; - _LIBCPP_SUPPRESS_DEPRECATED_POP protected: - _Up __value_; + _ALIGNAS_TYPE(_Rp) char __value_[sizeof(_Rp)]; _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; @@ -1836,12 +1833,10 @@ public: _LIBCPP_HIDE_FROM_ABI __async_func(__async_func&& __f) : __f_(std::move(__f.__f_)) {} - _LIBCPP_HIDE_FROM_ABI _Rp operator()() { return __execute(__make_index_sequence<sizeof...(_Args) + 1>()); } - -private: - template <size_t... _Indices> - _LIBCPP_HIDE_FROM_ABI _Rp __execute(__index_sequence<_Indices...>) { - return std::__invoke(std::move(std::get<_Indices>(__f_))...); + _LIBCPP_HIDE_FROM_ABI _Rp operator()() { + return [&]<size_t... _Indices>(__index_sequence<_Indices...>) -> _Rp { + return std::__invoke(std::move(std::get<_Indices>(__f_))...); + }(__index_sequence_for<_Fp, _Args...>{}); } }; diff --git a/libcxx/include/initializer_list b/libcxx/include/initializer_list index 00e0d4e..44cd456 100644 --- a/libcxx/include/initializer_list +++ b/libcxx/include/initializer_list @@ -78,11 +78,17 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 initializer_list() _NOEXCEPT : __begin_(nullptr), __size_(0) {} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t size() const _NOEXCEPT { return __size_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t size() const _NOEXCEPT { + return __size_; + } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* begin() const _NOEXCEPT { return __begin_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* begin() const _NOEXCEPT { + return __begin_; + } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* end() const _NOEXCEPT { return __begin_ + __size_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* end() const _NOEXCEPT { + return __begin_ + __size_; + } }; template <class _Ep> diff --git a/libcxx/include/latch b/libcxx/include/latch index c3b8f62..33268d9 100644 --- a/libcxx/include/latch +++ b/libcxx/include/latch @@ -70,7 +70,9 @@ class latch { atomic<ptrdiff_t> __a_; public: - static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept { return numeric_limits<ptrdiff_t>::max(); } + [[nodiscard]] static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept { + return numeric_limits<ptrdiff_t>::max(); + } inline _LIBCPP_HIDE_FROM_ABI constexpr explicit latch(ptrdiff_t __expected) : __a_(__expected) { _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( @@ -97,7 +99,7 @@ public: if (__old == __update) __a_.notify_all(); } - inline _LIBCPP_HIDE_FROM_ABI bool try_wait() const noexcept { + [[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool try_wait() const noexcept { auto __value = __a_.load(memory_order_acquire); return try_wait_impl(__value); } diff --git a/libcxx/include/limits b/libcxx/include/limits index e8581cf..ff40d20 100644 --- a/libcxx/include/limits +++ b/libcxx/include/limits @@ -107,7 +107,7 @@ template<> class numeric_limits<cv long double>; #else # include <__config> # include <__type_traits/is_arithmetic.h> -# include <__type_traits/is_signed.h> +# include <__type_traits/is_same.h> # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -217,10 +217,10 @@ protected: static _LIBCPP_CONSTEXPR const bool is_iec559 = false; static _LIBCPP_CONSTEXPR const bool is_bounded = true; - static _LIBCPP_CONSTEXPR const bool is_modulo = !std::is_signed<_Tp>::value; + static _LIBCPP_CONSTEXPR const bool is_modulo = !is_signed; # if defined(__i386__) || defined(__x86_64__) || defined(__wasm__) - static _LIBCPP_CONSTEXPR const bool traps = true; + static _LIBCPP_CONSTEXPR const bool traps = is_same<decltype(+_Tp(0)), _Tp>::value; # else static _LIBCPP_CONSTEXPR const bool traps = false; # endif diff --git a/libcxx/include/list b/libcxx/include/list index 2898a45..a5c84ca 100644 --- a/libcxx/include/list +++ b/libcxx/include/list @@ -774,57 +774,71 @@ public: _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __x); - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT; + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT; - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return this->__size_; } + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { + return this->__size_; + } [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __base::empty(); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return std::min<size_type>(this->__node_alloc_max_size(), numeric_limits<difference_type >::max()); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __base::begin(); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __base::begin(); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __base::end(); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __base::end(); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { + return __base::begin(); + } + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { + return __base::begin(); + } + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { + return __base::end(); + } + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { + return __base::end(); + } + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return __base::begin(); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return __base::end(); } + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { + return __base::end(); + } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator + rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator + crbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(begin()); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference front() { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference front() { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::front called on empty list"); return __base::__end_.__next_->__as_node()->__get_value(); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference front() const { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference front() const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::front called on empty list"); return __base::__end_.__next_->__as_node()->__get_value(); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference back() { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference back() { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::back called on empty list"); return __base::__end_.__prev_->__as_node()->__get_value(); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference back() const { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference back() const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::back called on empty list"); return __base::__end_.__prev_->__as_node()->__get_value(); } diff --git a/libcxx/include/map b/libcxx/include/map index cc8b876..0dca11c 100644 --- a/libcxx/include/map +++ b/libcxx/include/map @@ -995,7 +995,7 @@ public: _LIBCPP_HIDE_FROM_ABI map(map&& __m) = default; - _LIBCPP_HIDE_FROM_ABI map(map&& __m, const allocator_type& __a); + _LIBCPP_HIDE_FROM_ABI map(map&& __m, const allocator_type& __a) : __tree_(std::move(__m.__tree_), __a) {} _LIBCPP_HIDE_FROM_ABI map& operator=(map&& __m) = default; @@ -1023,10 +1023,7 @@ public: _LIBCPP_HIDE_FROM_ABI explicit map(const allocator_type& __a) : __tree_(typename __base::allocator_type(__a)) {} - _LIBCPP_HIDE_FROM_ABI map(const map& __m, const allocator_type& __a) - : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a)) { - insert(__m.begin(), __m.end()); - } + _LIBCPP_HIDE_FROM_ABI map(const map& __m, const allocator_type& __alloc) : __tree_(__m.__tree_, __alloc) {} _LIBCPP_HIDE_FROM_ABI ~map() { static_assert(sizeof(std::__diagnose_non_const_comparator<_Key, _Compare>()), ""); } @@ -1427,18 +1424,6 @@ map(initializer_list<pair<_Key, _Tp>>, _Allocator) # ifndef _LIBCPP_CXX03_LANG template <class _Key, class _Tp, class _Compare, class _Allocator> -map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a) - : __tree_(std::move(__m.__tree_), typename __base::allocator_type(__a)) { - if (__a != __m.get_allocator()) { - const_iterator __e = cend(); - while (!__m.empty()) { - __tree_.__insert_unique_from_orphaned_node( - __e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__get_value())); - } - } -} - -template <class _Key, class _Tp, class _Compare, class _Allocator> _Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) { return __tree_.__emplace_unique(std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple()) .first->second; @@ -1683,7 +1668,7 @@ public: _LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m) = default; - _LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m, const allocator_type& __a); + _LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m, const allocator_type& __a) : __tree_(std::move(__m.__tree_), __a) {} _LIBCPP_HIDE_FROM_ABI multimap& operator=(multimap&& __m) = default; @@ -1712,10 +1697,7 @@ public: _LIBCPP_HIDE_FROM_ABI explicit multimap(const allocator_type& __a) : __tree_(typename __base::allocator_type(__a)) {} - _LIBCPP_HIDE_FROM_ABI multimap(const multimap& __m, const allocator_type& __a) - : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a)) { - insert(__m.begin(), __m.end()); - } + _LIBCPP_HIDE_FROM_ABI multimap(const multimap& __m, const allocator_type& __a) : __tree_(__m.__tree_, __a) {} _LIBCPP_HIDE_FROM_ABI ~multimap() { static_assert(sizeof(std::__diagnose_non_const_comparator<_Key, _Compare>()), ""); @@ -1990,19 +1972,6 @@ multimap(initializer_list<pair<_Key, _Tp>>, _Allocator) -> multimap<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>; # endif -# ifndef _LIBCPP_CXX03_LANG -template <class _Key, class _Tp, class _Compare, class _Allocator> -multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const allocator_type& __a) - : __tree_(std::move(__m.__tree_), typename __base::allocator_type(__a)) { - if (__a != __m.get_allocator()) { - const_iterator __e = cend(); - while (!__m.empty()) - __tree_.__insert_multi_from_orphaned_node( - __e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__get_value())); - } -} -# endif - template <class _Key, class _Tp, class _Compare, class _Allocator> inline _LIBCPP_HIDE_FROM_ABI bool operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) { diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index 2266a1d..bbc2617 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -6,6 +6,8 @@ module std_config [system] { textual header "__configuration/abi.h" textual header "__configuration/availability.h" textual header "__configuration/compiler.h" + textual header "__configuration/experimental.h" + textual header "__configuration/hardening.h" textual header "__configuration/language.h" textual header "__configuration/platform.h" textual header "version" @@ -124,10 +126,6 @@ module std_core [system] { header "__type_traits/is_base_of.h" export std_core.type_traits.integral_constant } - module is_bounded_array { - header "__type_traits/is_bounded_array.h" - export std_core.type_traits.integral_constant - } module is_callable { header "__type_traits/is_callable.h" export std_core.type_traits.integral_constant @@ -269,10 +267,6 @@ module std_core [system] { header "__type_traits/is_referenceable.h" export std_core.type_traits.integral_constant } - module is_replaceable { - header "__type_traits/is_replaceable.h" - export std_core.type_traits.integral_constant - } module is_same { header "__type_traits/is_same.h" export std_core.type_traits.integral_constant @@ -325,10 +319,6 @@ module std_core [system] { header "__type_traits/is_trivially_relocatable.h" export std_core.type_traits.integral_constant } - module is_unbounded_array { - header "__type_traits/is_unbounded_array.h" - export std_core.type_traits.integral_constant - } module is_union { header "__type_traits/is_union.h" export std_core.type_traits.integral_constant @@ -839,6 +829,7 @@ module std [system] { module simd_utils { header "__algorithm/simd_utils.h" } module sort_heap { header "__algorithm/sort_heap.h" } module sort { header "__algorithm/sort.h" } + module specialized_algorithms { header "__algorithm/specialized_algorithms.h" } module stable_partition { header "__algorithm/stable_partition.h" } module stable_sort { header "__algorithm/stable_sort.h" @@ -1593,6 +1584,7 @@ module std [system] { textual header "__locale_dir/support/fuchsia.h" textual header "__locale_dir/support/linux.h" textual header "__locale_dir/support/netbsd.h" + textual header "__locale_dir/support/newlib.h" textual header "__locale_dir/support/no_locale/characters.h" textual header "__locale_dir/support/no_locale/strtonum.h" textual header "__locale_dir/support/windows.h" @@ -1601,7 +1593,6 @@ module std [system] { module locale_base_api { textual header "__locale_dir/locale_base_api/bsd_locale_fallbacks.h" textual header "__locale_dir/locale_base_api/ibm.h" - textual header "__locale_dir/locale_base_api/musl.h" textual header "__locale_dir/locale_base_api/openbsd.h" } export * @@ -1639,7 +1630,6 @@ module std [system] { module memory { module addressof { header "__memory/addressof.h" } module align { header "__memory/align.h" } - module aligned_alloc { header "__memory/aligned_alloc.h" } module allocate_at_least { header "__memory/allocate_at_least.h" } module allocation_guard { header "__memory/allocation_guard.h" } module allocator { @@ -1671,7 +1661,10 @@ module std [system] { } module raw_storage_iterator { header "__memory/raw_storage_iterator.h" } module shared_count { header "__memory/shared_count.h" } - module shared_ptr { header "__memory/shared_ptr.h" } + module shared_ptr { + header "__memory/shared_ptr.h" + export std.functional.hash + } module swap_allocator { header "__memory/swap_allocator.h" } module temp_value { header "__memory/temp_value.h" } module temporary_buffer { @@ -1684,6 +1677,7 @@ module std [system] { } module unique_ptr { header "__memory/unique_ptr.h" + export std.functional.hash } module unique_temporary_buffer { header "__memory/unique_temporary_buffer.h" @@ -2363,7 +2357,10 @@ module std [system] { module hash_table { header "__hash_table" } module node_handle { header "__node_handle" } module split_buffer { header "__split_buffer" } - module tree { header "__tree" } + module tree { + header "__tree" + export std.memory.unique_ptr + } module std_mbstate_t { header "__std_mbstate_t.h" export * @@ -2399,6 +2396,7 @@ module std [system] { header "coroutine" export * + export std.functional.hash } } // module std @@ -2439,10 +2437,6 @@ module std_stdatomic_h [system] { header "stdatomic.h" export * } -module std_stdbool_h [system] { - // <stdbool.h>'s __bool_true_false_are_defined macro requires textual inclusion. - textual header "stdbool.h" -} module std_stddef_h [system] { // <stddef.h> supports being included multiple times with different pre-defined macros textual header "stddef.h" diff --git a/libcxx/include/mutex b/libcxx/include/mutex index 0b81f1b..bec0185 100644 --- a/libcxx/include/mutex +++ b/libcxx/include/mutex @@ -229,12 +229,12 @@ public: recursive_mutex& operator=(const recursive_mutex&) = delete; void lock(); - bool try_lock() _NOEXCEPT; + [[__nodiscard__]] bool try_lock() _NOEXCEPT; void unlock() _NOEXCEPT; typedef __libcpp_recursive_mutex_t* native_handle_type; - _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; } }; class _LIBCPP_EXPORTED_FROM_ABI timed_mutex { @@ -251,14 +251,14 @@ public: public: void lock(); - bool try_lock() _NOEXCEPT; + [[__nodiscard__]] bool try_lock() _NOEXCEPT; template <class _Rep, class _Period> - _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) { return try_lock_until(chrono::steady_clock::now() + __d); } template <class _Clock, class _Duration> - _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) { using namespace chrono; unique_lock<mutex> __lk(__m_); bool __no_timeout = _Clock::now() < __t; @@ -288,14 +288,14 @@ public: recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete; void lock(); - bool try_lock() _NOEXCEPT; + [[__nodiscard__]] bool try_lock() _NOEXCEPT; template <class _Rep, class _Period> - _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) { return try_lock_until(chrono::steady_clock::now() + __d); } template <class _Clock, class _Duration> - _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) { using namespace chrono; __thread_id __id = this_thread::get_id(); unique_lock<mutex> __lk(__m_); @@ -320,7 +320,7 @@ public: }; template <class _L0, class _L1> -_LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) { +[[__nodiscard__]] _LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) { unique_lock<_L0> __u0(__l0, try_to_lock_t()); if (__u0.owns_lock()) { if (__l1.try_lock()) { @@ -335,7 +335,8 @@ _LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, # ifndef _LIBCPP_CXX03_LANG template <class _L0, class _L1, class _L2, class... _L3> -_LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) { +[[__nodiscard__]] _LIBCPP_NO_THREAD_SAFETY_ANALYSIS + _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) { int __r = 0; unique_lock<_L0> __u0(__l0, try_to_lock); if (__u0.owns_lock()) { diff --git a/libcxx/include/optional b/libcxx/include/optional index ef1bfd3..7b979d3d 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -186,6 +186,71 @@ namespace std { template<class T> optional(T) -> optional<T>; + template<class T> + class optional<T&> { // since C++26 + public: + using value_type = T; + using iterator = implementation-defined; // see [optional.ref.iterators] + + public: + // [optional.ref.ctor], constructors + constexpr optional() noexcept = default; + constexpr optional(nullopt_t) noexcept : optional() {} + constexpr optional(const optional& rhs) noexcept = default; + + template<class Arg> + constexpr explicit optional(in_place_t, Arg&& arg); + template<class U> + constexpr explicit(see below) optional(U&& u) noexcept(see below); + template<class U> + constexpr explicit(see below) optional(optional<U>& rhs) noexcept(see below); + template<class U> + constexpr explicit(see below) optional(const optional<U>& rhs) noexcept(see below); + template<class U> + constexpr explicit(see below) optional(optional<U>&& rhs) noexcept(see below); + template<class U> + constexpr explicit(see below) optional(const optional<U>&& rhs) noexcept(see below); + + constexpr ~optional() = default; + + // [optional.ref.assign], assignment + constexpr optional& operator=(nullopt_t) noexcept; + constexpr optional& operator=(const optional& rhs) noexcept = default; + + template<class U> constexpr T& emplace(U&& u) noexcept(see below); + + // [optional.ref.swap], swap + constexpr void swap(optional& rhs) noexcept; + + // [optional.ref.iterators], iterator support + constexpr iterator begin() const noexcept; + constexpr iterator end() const noexcept; + + // [optional.ref.observe], observers + constexpr T* operator->() const noexcept; + constexpr T& operator*() const noexcept; + constexpr explicit operator bool() const noexcept; + constexpr bool has_value() const noexcept; + constexpr T& value() const; // freestanding-deleted + template<class U = remove_cv_t<T>> + constexpr remove_cv_t<T> value_or(U&& u) const; + + // [optional.ref.monadic], monadic operations + template<class F> constexpr auto and_then(F&& f) const; + template<class F> constexpr optional<invoke_result_t<F, T&>> transform(F&& f) const; + template<class F> constexpr optional or_else(F&& f) const; + + // [optional.ref.mod], modifiers + constexpr void reset() noexcept; + + private: + T* val = nullptr; // exposition only + + // [optional.ref.expos], exposition only helper functions + template<class U> + constexpr void convert-ref-init-val(U&& u); // exposition only + }; + } // namespace std */ @@ -210,6 +275,7 @@ namespace std { # include <__iterator/wrap_iter.h> # include <__memory/addressof.h> # include <__memory/construct_at.h> +# include <__ranges/enable_borrowed_range.h> # include <__ranges/enable_view.h> # include <__tuple/sfinae_helpers.h> # include <__type_traits/add_pointer.h> @@ -230,7 +296,6 @@ namespace std { # include <__type_traits/is_nothrow_constructible.h> # include <__type_traits/is_object.h> # include <__type_traits/is_reference.h> -# include <__type_traits/is_replaceable.h> # include <__type_traits/is_same.h> # include <__type_traits/is_scalar.h> # include <__type_traits/is_swappable.h> @@ -238,8 +303,8 @@ namespace std { # include <__type_traits/is_trivially_constructible.h> # include <__type_traits/is_trivially_destructible.h> # include <__type_traits/is_trivially_relocatable.h> -# include <__type_traits/is_unbounded_array.h> # include <__type_traits/negation.h> +# include <__type_traits/reference_constructs_from_temporary.h> # include <__type_traits/remove_const.h> # include <__type_traits/remove_cv.h> # include <__type_traits/remove_cvref.h> @@ -410,39 +475,30 @@ struct __optional_storage_base : __optional_destruct_base<_Tp> { __construct(std::forward<_That>(__opt).__get()); } } + + template <class _Up> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from_val(_Up&& __val) { + this->__get() = std::forward<_Up>(__val); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __swap(__optional_storage_base& __rhs) { + using std::swap; + swap(this->__get(), __rhs.__get()); + } }; -// optional<T&> is currently required to be ill-formed. However, it may -// be allowed in the future. For this reason, it has already been implemented -// to ensure we can make the change in an ABI-compatible manner. template <class _Tp> struct __optional_storage_base<_Tp, true> { using value_type = _Tp; using __raw_type _LIBCPP_NODEBUG = remove_reference_t<_Tp>; __raw_type* __value_; - template <class _Up> - static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() { - using _RawUp = __libcpp_remove_reference_t<_Up>; - using _UpPtr = _RawUp*; - using _RawTp = __libcpp_remove_reference_t<_Tp>; - using _TpPtr = _RawTp*; - using _CheckLValueArg = - integral_constant<bool, - (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value) || - is_same<_RawUp, reference_wrapper<_RawTp>>::value || - is_same<_RawUp, reference_wrapper<__remove_const_t<_RawTp>>>::value >; - return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value) || - (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value && - is_convertible<_UpPtr, _TpPtr>::value); - } - _LIBCPP_HIDE_FROM_ABI constexpr __optional_storage_base() noexcept : __value_(nullptr) {} template <class _UArg> _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg) : __value_(std::addressof(__uarg)) { - static_assert(__can_bind_reference<_UArg>(), + static_assert(!__reference_constructs_from_temporary_v<_Tp, _UArg>, "Attempted to construct a reference element in tuple from a " "possible temporary"); } @@ -458,7 +514,7 @@ struct __optional_storage_base<_Tp, true> { template <class _UArg> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val) { _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage"); - static_assert(__can_bind_reference<_UArg>(), + static_assert(!__reference_constructs_from_temporary_v<_Tp, _UArg>, "Attempted to construct a reference element in tuple from a " "possible temporary"); __value_ = std::addressof(__val); @@ -482,6 +538,15 @@ struct __optional_storage_base<_Tp, true> { __construct(std::forward<_That>(__opt).__get()); } } + + template <class _Up> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from_val(_Up&& __val) noexcept { + __value_ = std::addressof(__val); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __swap(__optional_storage_base& __rhs) noexcept { + std::swap(__value_, __rhs.__value_); + } }; template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value> @@ -593,6 +658,10 @@ constexpr bool ranges::enable_view<optional<_Tp>> = true; template <class _Tp> constexpr range_format format_kind<optional<_Tp>> = range_format::disabled; + +template <class _Tp> +constexpr bool ranges::enable_borrowed_range<optional<_Tp&>> = true; + # endif # if _LIBCPP_STD_VER >= 20 @@ -607,19 +676,19 @@ struct __is_std_optional : false_type {}; template <class _Tp> struct __is_std_optional<optional<_Tp>> : true_type {}; -template <class _Tp> -class _LIBCPP_DECLSPEC_EMPTY_BASES optional - : private __optional_move_assign_base<_Tp>, - private __optional_sfinae_ctor_base_t<_Tp>, - private __optional_sfinae_assign_base_t<_Tp> { - using __base _LIBCPP_NODEBUG = __optional_move_assign_base<_Tp>; +template <class _Tp, class = void> +struct __optional_iterator {}; - using __pointer _LIBCPP_NODEBUG = std::add_pointer_t<_Tp>; - using __const_pointer _LIBCPP_NODEBUG = std::add_pointer_t<const _Tp>; +template <class _Tp> +struct __optional_iterator< + _Tp, + enable_if_t<!(is_lvalue_reference_v<_Tp> && is_function_v<__libcpp_remove_reference_t<_Tp>>) && + !(is_lvalue_reference_v<_Tp> && is_array_v<__libcpp_remove_reference_t<_Tp>>)> > { +private: + using __pointer _LIBCPP_NODEBUG = add_pointer_t<remove_reference_t<_Tp>>; + using __const_pointer _LIBCPP_NODEBUG = add_pointer_t<const remove_reference_t<_Tp>>; public: - using value_type = _Tp; - # if _LIBCPP_STD_VER >= 26 # ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL using iterator = __bounded_iter<__wrap_iter<__pointer>>; @@ -628,20 +697,86 @@ public: using iterator = __wrap_iter<__pointer>; using const_iterator = __wrap_iter<__const_pointer>; # endif + + // [optional.iterators], iterator support + _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() noexcept { + auto& __derived_self = static_cast<optional<_Tp>&>(*this); + auto __ptr = [&__derived_self]() { + if constexpr (is_lvalue_reference_v<_Tp>) { + return __derived_self.has_value() ? std::addressof(__derived_self.__get()) : nullptr; + } + return std::addressof(__derived_self.__get()); + }(); + +# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL + return std::__make_bounded_iter( + __wrap_iter<__pointer>(__ptr), + __wrap_iter<__pointer>(__ptr), + __wrap_iter<__pointer>(__ptr) + (__derived_self.has_value() ? 1 : 0)); +# else + return iterator(__ptr); +# endif + } + + _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept { + auto& __derived_self = static_cast<const optional<_Tp>&>(*this); + auto* __ptr = [&__derived_self]() { + if constexpr (is_lvalue_reference_v<_Tp>) { + return __derived_self.has_value() ? std::addressof(__derived_self.__get()) : nullptr; + } + return std::addressof(__derived_self.__get()); + }(); + +# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL + return std::__make_bounded_iter( + __wrap_iter<__const_pointer>(__ptr), + __wrap_iter<__const_pointer>(__ptr), + __wrap_iter<__const_pointer>(__ptr) + (__derived_self.has_value() ? 1 : 0)); +# else + return const_iterator(__ptr); +# endif + } + + _LIBCPP_HIDE_FROM_ABI constexpr iterator end() noexcept { + return begin() + (static_cast<optional<_Tp>&>(*this).has_value() ? 1 : 0); + } + _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept { + return begin() + (static_cast<const optional<_Tp>&>(*this).has_value() ? 1 : 0); + } # endif +}; + +template <class _Tp> +class _LIBCPP_DECLSPEC_EMPTY_BASES optional + : private __optional_move_assign_base<_Tp>, + private __optional_sfinae_ctor_base_t<_Tp>, + private __optional_sfinae_assign_base_t<_Tp>, + public __optional_iterator<_Tp> { + using __base _LIBCPP_NODEBUG = __optional_move_assign_base<_Tp>; + +public: + using value_type = __libcpp_remove_reference_t<_Tp>; + using __trivially_relocatable _LIBCPP_NODEBUG = conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, optional, void>; - using __replaceable _LIBCPP_NODEBUG = conditional_t<__is_replaceable_v<_Tp>, optional, void>; private: - // Disable the reference extension using this static assert. - static_assert(!is_same_v<__remove_cvref_t<value_type>, in_place_t>, + static_assert(!is_same_v<__remove_cvref_t<_Tp>, in_place_t>, "instantiation of optional with in_place_t is ill-formed"); - static_assert(!is_same_v<__remove_cvref_t<value_type>, nullopt_t>, - "instantiation of optional with nullopt_t is ill-formed"); - static_assert(!is_reference_v<value_type>, "instantiation of optional with a reference type is ill-formed"); - static_assert(is_destructible_v<value_type>, "instantiation of optional with a non-destructible type is ill-formed"); - static_assert(!is_array_v<value_type>, "instantiation of optional with an array type is ill-formed"); + static_assert(!is_same_v<__remove_cvref_t<_Tp>, nullopt_t>, "instantiation of optional with nullopt_t is ill-formed"); +# if _LIBCPP_STD_VER >= 26 + static_assert(!is_rvalue_reference_v<_Tp>, "instantiation of optional with an rvalue reference type is ill-formed"); +# else + static_assert(!is_reference_v<_Tp>, "instantiation of optional with a reference type is ill-formed"); +# endif + static_assert(is_destructible_v<_Tp>, "instantiation of optional with a non-destructible type is ill-formed"); + static_assert(!is_array_v<_Tp>, "instantiation of optional with an array type is ill-formed"); + +# if _LIBCPP_STD_VER >= 26 + template <class _Up> + constexpr static bool __libcpp_opt_ref_ctor_deleted = + is_lvalue_reference_v<_Tp> && reference_constructs_from_temporary_v<_Tp, _Up>; +# endif // LWG2756: conditionally explicit conversion from _Up struct _CheckOptionalArgsConstructor { @@ -716,18 +851,15 @@ public: template <class _InPlaceT, class... _Args, - enable_if_t<_And<_IsSame<_InPlaceT, in_place_t>, is_constructible<value_type, _Args...>>::value, int> = 0> + enable_if_t<_And<_IsSame<_InPlaceT, in_place_t>, is_constructible<_Tp, _Args...>>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_InPlaceT, _Args&&... __args) : __base(in_place, std::forward<_Args>(__args)...) {} - template <class _Up, - class... _Args, - enable_if_t<is_constructible_v<value_type, initializer_list<_Up>&, _Args...>, int> = 0> + template <class _Up, class... _Args, enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0> _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) : __base(in_place, __il, std::forward<_Args>(__args)...) {} - template <class _Up = value_type, - enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>(), int> = 0> + template <class _Up = _Tp, enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>(), int> = 0> _LIBCPP_HIDE_FROM_ABI constexpr optional(_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {} template <class _Up = remove_cv_t<_Tp>, @@ -754,6 +886,38 @@ public: this->__construct_from(std::move(__v)); } + // deleted optional<T&> constructors +# if _LIBCPP_STD_VER >= 26 + template <class _Up, class... _Args, enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0> + requires __libcpp_opt_ref_ctor_deleted<_Up> + explicit optional(in_place_t, initializer_list<_Up>, _Args&&...) = delete; + + template <class _Up = _Tp, enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>(), int> = 0> + requires __libcpp_opt_ref_ctor_deleted<_Up> + optional(_Up&&) = delete; + + template <class _Up = remove_cv_t<_Tp>, + enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>(), int> = 0> + requires __libcpp_opt_ref_ctor_deleted<_Up> + explicit optional(_Up&&) = delete; + + template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>(), int> = 0> + requires __libcpp_opt_ref_ctor_deleted<_Up> + optional(const optional<_Up>&) = delete; + + template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>(), int> = 0> + requires __libcpp_opt_ref_ctor_deleted<_Up> + explicit optional(const optional<_Up>&) = delete; + + template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_implicit<_Up>(), int> = 0> + requires __libcpp_opt_ref_ctor_deleted<_Up> + optional(optional<_Up>&&) = delete; + + template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_explicit<_Up>(), int> = 0> + requires __libcpp_opt_ref_ctor_deleted<_Up> + explicit optional(optional<_Up>&&) = delete; +# endif + # if _LIBCPP_STD_VER >= 23 template <class _Tag, class _Fp, @@ -772,15 +936,15 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(optional&&) = default; // LWG2756 - template <class _Up = remove_cv_t<value_type>, + template <class _Up = remove_cv_t<_Tp>, enable_if_t<_And<_IsNotSame<__remove_cvref_t<_Up>, optional>, - _Or<_IsNotSame<__remove_cvref_t<_Up>, value_type>, _Not<is_scalar<value_type>>>, - is_constructible<value_type, _Up>, - is_assignable<value_type&, _Up>>::value, + _Or<_IsNotSame<__remove_cvref_t<_Up>, _Tp>, _Not<is_scalar<_Tp>>>, + is_constructible<_Tp, _Up>, + is_assignable<_Tp&, _Up>>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(_Up&& __v) { if (this->has_value()) - this->__get() = std::forward<_Up>(__v); + this->__assign_from_val(std::forward<_Up>(__v)); else this->__construct(std::forward<_Up>(__v)); return *this; @@ -800,7 +964,7 @@ public: return *this; } - template <class... _Args, enable_if_t<is_constructible_v<value_type, _Args...>, int> = 0> + template <class... _Args, enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) { reset(); this->__construct(std::forward<_Args>(__args)...); @@ -809,7 +973,12 @@ public: template <class _Up, class... _Args, - enable_if_t<is_constructible_v<value_type, initializer_list<_Up>&, _Args...>, int> = 0> + enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...> +# if _LIBCPP_STD_VER >= 26 + && !reference_constructs_from_temporary_v<_Tp&, _Up> +# endif + , + int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) { reset(); this->__construct(__il, std::forward<_Args>(__args)...); @@ -817,11 +986,10 @@ public: } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void - swap(optional& __opt) noexcept(is_nothrow_move_constructible_v<value_type> && is_nothrow_swappable_v<value_type>) { + swap(optional& __opt) noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_swappable_v<_Tp>) { if (this->has_value() == __opt.has_value()) { - using std::swap; if (this->has_value()) - swap(this->__get(), __opt.__get()); + this->__swap(__opt); } else { if (this->has_value()) { __opt.__construct(std::move(this->__get())); @@ -833,60 +1001,32 @@ public: } } -# if _LIBCPP_STD_VER >= 26 - // [optional.iterators], iterator support - _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() noexcept { -# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL - return std::__make_bounded_iter( - std::__wrap_iter<__pointer>(std::addressof(this->__get())), - std::__wrap_iter<__pointer>(std::addressof(this->__get())), - std::__wrap_iter<__pointer>(std::addressof(this->__get()) + (this->has_value() ? 1 : 0))); -# else - return iterator(std::addressof(this->__get())); -# endif - } - - _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept { -# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL - return std::__make_bounded_iter( - std::__wrap_iter<__const_pointer>(std::addressof(this->__get())), - std::__wrap_iter<__const_pointer>(std::addressof(this->__get())), - std::__wrap_iter<__const_pointer>(std::addressof(this->__get()) + (this->has_value() ? 1 : 0))); -# else - return const_iterator(std::addressof(this->__get())); -# endif - } - - _LIBCPP_HIDE_FROM_ABI constexpr iterator end() noexcept { return begin() + (this->has_value() ? 1 : 0); } - _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept { return begin() + (this->has_value() ? 1 : 0); } -# endif - - _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type const> operator->() const noexcept { + _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp const> operator->() const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value"); return std::addressof(this->__get()); } - _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type> operator->() noexcept { + _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp> operator->() noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value"); return std::addressof(this->__get()); } - _LIBCPP_HIDE_FROM_ABI constexpr const value_type& operator*() const& noexcept { + _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value"); return this->__get(); } - _LIBCPP_HIDE_FROM_ABI constexpr value_type& operator*() & noexcept { + _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value"); return this->__get(); } - _LIBCPP_HIDE_FROM_ABI constexpr value_type&& operator*() && noexcept { + _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value"); return std::move(this->__get()); } - _LIBCPP_HIDE_FROM_ABI constexpr const value_type&& operator*() const&& noexcept { + _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value"); return std::move(this->__get()); } @@ -896,48 +1036,66 @@ public: using __base::__get; using __base::has_value; - _LIBCPP_HIDE_FROM_ABI constexpr value_type const& value() const& { + _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& value() const& { if (!this->has_value()) std::__throw_bad_optional_access(); return this->__get(); } - _LIBCPP_HIDE_FROM_ABI constexpr value_type& value() & { + _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & { if (!this->has_value()) std::__throw_bad_optional_access(); return this->__get(); } - _LIBCPP_HIDE_FROM_ABI constexpr value_type&& value() && { + _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && { if (!this->has_value()) std::__throw_bad_optional_access(); return std::move(this->__get()); } - _LIBCPP_HIDE_FROM_ABI constexpr value_type const&& value() const&& { + _LIBCPP_HIDE_FROM_ABI constexpr _Tp const&& value() const&& { if (!this->has_value()) std::__throw_bad_optional_access(); return std::move(this->__get()); } template <class _Up = remove_cv_t<_Tp>> - _LIBCPP_HIDE_FROM_ABI constexpr value_type value_or(_Up&& __v) const& { - static_assert(is_copy_constructible_v<value_type>, "optional<T>::value_or: T must be copy constructible"); - static_assert(is_convertible_v<_Up, value_type>, "optional<T>::value_or: U must be convertible to T"); - return this->has_value() ? this->__get() : static_cast<value_type>(std::forward<_Up>(__v)); +# if _LIBCPP_STD_VER >= 26 + requires(!(is_lvalue_reference_v<_Tp> && is_function_v<__libcpp_remove_reference_t<_Tp>>) && + !(is_lvalue_reference_v<_Tp> && is_array_v<__libcpp_remove_reference_t<_Tp>>)) +# endif + _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& { + static_assert(is_copy_constructible_v<_Tp>, "optional<T>::value_or: T must be copy constructible"); + static_assert(is_convertible_v<_Up, _Tp>, "optional<T>::value_or: U must be convertible to T"); + return this->has_value() ? this->__get() : static_cast<_Tp>(std::forward<_Up>(__v)); + } + + template <class _Up = remove_cv_t<_Tp>> +# if _LIBCPP_STD_VER >= 26 + requires(!is_lvalue_reference_v<_Tp>) +# endif + _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && { + static_assert(is_move_constructible_v<_Tp>, "optional<T>::value_or: T must be move constructible"); + static_assert(is_convertible_v<_Up, _Tp>, "optional<T>::value_or: U must be convertible to T"); + return this->has_value() ? std::move(this->__get()) : static_cast<_Tp>(std::forward<_Up>(__v)); } +# if _LIBCPP_STD_VER >= 26 template <class _Up = remove_cv_t<_Tp>> - _LIBCPP_HIDE_FROM_ABI constexpr value_type value_or(_Up&& __v) && { - static_assert(is_move_constructible_v<value_type>, "optional<T>::value_or: T must be move constructible"); - static_assert(is_convertible_v<_Up, value_type>, "optional<T>::value_or: U must be convertible to T"); - return this->has_value() ? std::move(this->__get()) : static_cast<value_type>(std::forward<_Up>(__v)); + requires(is_lvalue_reference_v<_Tp> && + !(is_function_v<__libcpp_remove_reference_t<_Tp>> || is_array_v<__libcpp_remove_reference_t<_Tp>>)) + _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && { + static_assert(is_move_constructible_v<_Tp>, "optional<T>::value_or: T must be move constructible"); + static_assert(is_convertible_v<_Up, _Tp>, "optional<T>::value_or: U must be convertible to T"); + return this->has_value() ? this->__get() : static_cast<_Tp>(std::forward<_Up>(__v)); } +# endif # if _LIBCPP_STD_VER >= 23 template <class _Func> _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & { - using _Up = invoke_result_t<_Func, value_type&>; + using _Up = invoke_result_t<_Func, _Tp&>; static_assert(__is_std_optional<remove_cvref_t<_Up>>::value, "Result of f(value()) must be a specialization of std::optional"); if (*this) @@ -947,7 +1105,7 @@ public: template <class _Func> _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& { - using _Up = invoke_result_t<_Func, const value_type&>; + using _Up = invoke_result_t<_Func, const _Tp&>; static_assert(__is_std_optional<remove_cvref_t<_Up>>::value, "Result of f(value()) must be a specialization of std::optional"); if (*this) @@ -957,7 +1115,7 @@ public: template <class _Func> _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && { - using _Up = invoke_result_t<_Func, value_type&&>; + using _Up = invoke_result_t<_Func, _Tp&&>; static_assert(__is_std_optional<remove_cvref_t<_Up>>::value, "Result of f(std::move(value())) must be a specialization of std::optional"); if (*this) @@ -967,7 +1125,7 @@ public: template <class _Func> _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& { - using _Up = invoke_result_t<_Func, const value_type&&>; + using _Up = invoke_result_t<_Func, const _Tp&&>; static_assert(__is_std_optional<remove_cvref_t<_Up>>::value, "Result of f(std::move(value())) must be a specialization of std::optional"); if (*this) @@ -977,7 +1135,7 @@ public: template <class _Func> _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & { - using _Up = remove_cv_t<invoke_result_t<_Func, value_type&>>; + using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&>>; static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array"); static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t"); static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t"); @@ -989,7 +1147,7 @@ public: template <class _Func> _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& { - using _Up = remove_cv_t<invoke_result_t<_Func, const value_type&>>; + using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&>>; static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array"); static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t"); static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t"); @@ -1001,7 +1159,7 @@ public: template <class _Func> _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && { - using _Up = remove_cv_t<invoke_result_t<_Func, value_type&&>>; + using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&&>>; static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array"); static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t"); static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t"); @@ -1013,7 +1171,7 @@ public: template <class _Func> _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& { - using _Up = remove_cvref_t<invoke_result_t<_Func, const value_type&&>>; + using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&&>>; static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array"); static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t"); static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t"); @@ -1025,7 +1183,7 @@ public: template <invocable _Func> _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) const& - requires is_copy_constructible_v<value_type> + requires is_copy_constructible_v<_Tp> { static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>, "Result of f() should be the same type as this optional"); @@ -1036,7 +1194,7 @@ public: template <invocable _Func> _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) && - requires is_move_constructible_v<value_type> + requires is_move_constructible_v<_Tp> { static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>, "Result of f() should be the same type as this optional"); @@ -1338,7 +1496,15 @@ swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } -template <class _Tp> +struct __make_optional_barrier_tag { + explicit __make_optional_barrier_tag() = default; +}; + +template < +# if _LIBCPP_STD_VER >= 26 + __make_optional_barrier_tag = __make_optional_barrier_tag{}, +# endif + class _Tp> _LIBCPP_HIDE_FROM_ABI constexpr optional<decay_t<_Tp>> make_optional(_Tp&& __v) { return optional<decay_t<_Tp>>(std::forward<_Tp>(__v)); } diff --git a/libcxx/include/queue b/libcxx/include/queue index b4b79fb..a1686bc 100644 --- a/libcxx/include/queue +++ b/libcxx/include/queue @@ -376,12 +376,12 @@ public: # endif // _LIBCPP_CXX03_LANG [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const { return c.empty(); } - _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); } - _LIBCPP_HIDE_FROM_ABI reference front() { return c.front(); } - _LIBCPP_HIDE_FROM_ABI const_reference front() const { return c.front(); } - _LIBCPP_HIDE_FROM_ABI reference back() { return c.back(); } - _LIBCPP_HIDE_FROM_ABI const_reference back() const { return c.back(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference front() { return c.front(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference front() const { return c.front(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference back() { return c.back(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference back() const { return c.back(); } _LIBCPP_HIDE_FROM_ABI void push(const value_type& __v) { c.push_back(__v); } # ifndef _LIBCPP_CXX03_LANG @@ -664,8 +664,10 @@ public: # endif [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI bool empty() const { return c.empty(); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); } - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference top() const { return c.front(); } + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); } + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference top() const { + return c.front(); + } _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void push(const value_type& __v); # ifndef _LIBCPP_CXX03_LANG diff --git a/libcxx/include/regex b/libcxx/include/regex index 9bbc3a6..b6c1951 100644 --- a/libcxx/include/regex +++ b/libcxx/include/regex @@ -1004,7 +1004,7 @@ public: typedef _CharT char_type; typedef basic_string<char_type> string_type; typedef locale locale_type; -# if defined(__BIONIC__) || defined(_NEWLIB_VERSION) +# if defined(__BIONIC__) || _LIBCPP_LIBC_NEWLIB // Originally bionic's ctype_base used its own ctype masks because the // builtin ctype implementation wasn't in libc++ yet. Bionic's ctype mask // was only 8 bits wide and already saturated, so it used a wider type here @@ -1013,9 +1013,7 @@ public: // implementation, but this was not updated to match. Since then Android has // needed to maintain a stable libc++ ABI, and this can't be changed without // an ABI break. - // We also need this workaround for newlib since _NEWLIB_VERSION is not - // defined yet inside __config, so we can't set the - // _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE macro. Additionally, newlib is + // We also need this workaround for newlib since newlib is // often used for space constrained environments, so it makes sense not to // duplicate the ctype table. typedef uint16_t char_class_type; diff --git a/libcxx/include/scoped_allocator b/libcxx/include/scoped_allocator index 74effc5..c72c470 100644 --- a/libcxx/include/scoped_allocator +++ b/libcxx/include/scoped_allocator @@ -434,10 +434,10 @@ public: piecewise_construct, __transform_tuple(typename __uses_alloc_ctor< _T1, inner_allocator_type&, _Args1... >::type(), std::move(__x), - __make_index_sequence<sizeof...(_Args1)>()), + __index_sequence_for<_Args1...>()), __transform_tuple(typename __uses_alloc_ctor< _T2, inner_allocator_type&, _Args2... >::type(), std::move(__y), - __make_index_sequence<sizeof...(_Args2)>())); + __index_sequence_for<_Args2...>())); } template <class _T1, class _T2> diff --git a/libcxx/include/semaphore b/libcxx/include/semaphore index 99c4ad2..1f19d50 100644 --- a/libcxx/include/semaphore +++ b/libcxx/include/semaphore @@ -133,7 +133,7 @@ class counting_semaphore { public: static_assert(__least_max_value >= 0, "The least maximum value must be a positive number"); - static constexpr ptrdiff_t max() noexcept { return __least_max_value; } + [[nodiscard]] static constexpr ptrdiff_t max() noexcept { return __least_max_value; } _LIBCPP_HIDE_FROM_ABI constexpr explicit counting_semaphore(ptrdiff_t __count) : __semaphore_(__count) { _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( @@ -156,12 +156,12 @@ public: } _LIBCPP_HIDE_FROM_ABI void acquire() { __semaphore_.acquire(); } template <class _Rep, class _Period> - _LIBCPP_HIDE_FROM_ABI bool try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time) { return __semaphore_.try_acquire_for(chrono::duration_cast<chrono::nanoseconds>(__rel_time)); } - _LIBCPP_HIDE_FROM_ABI bool try_acquire() { return __semaphore_.try_acquire(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool try_acquire() { return __semaphore_.try_acquire(); } template <class _Clock, class _Duration> - _LIBCPP_HIDE_FROM_ABI bool try_acquire_until(chrono::time_point<_Clock, _Duration> const& __abs_time) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool try_acquire_until(chrono::time_point<_Clock, _Duration> const& __abs_time) { auto const __current = _Clock::now(); if (__current >= __abs_time) return try_acquire(); diff --git a/libcxx/include/set b/libcxx/include/set index d58b6e9..3d6f571 100644 --- a/libcxx/include/set +++ b/libcxx/include/set @@ -671,12 +671,10 @@ public: _LIBCPP_HIDE_FROM_ABI explicit set(const allocator_type& __a) : __tree_(__a) {} - _LIBCPP_HIDE_FROM_ABI set(const set& __s, const allocator_type& __a) : __tree_(__s.__tree_.value_comp(), __a) { - insert(__s.begin(), __s.end()); - } + _LIBCPP_HIDE_FROM_ABI set(const set& __s, const allocator_type& __alloc) : __tree_(__s.__tree_, __alloc) {} # ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI set(set&& __s, const allocator_type& __a); + _LIBCPP_HIDE_FROM_ABI set(set&& __s, const allocator_type& __alloc) : __tree_(std::move(__s.__tree_), __alloc) {} _LIBCPP_HIDE_FROM_ABI set(initializer_list<value_type> __il, const value_compare& __comp = value_compare()) : __tree_(__comp) { @@ -946,19 +944,6 @@ template <class _Key, class _Allocator, class = enable_if_t<__is_allocator_v<_Al set(initializer_list<_Key>, _Allocator) -> set<_Key, less<_Key>, _Allocator>; # endif -# ifndef _LIBCPP_CXX03_LANG - -template <class _Key, class _Compare, class _Allocator> -set<_Key, _Compare, _Allocator>::set(set&& __s, const allocator_type& __a) : __tree_(std::move(__s.__tree_), __a) { - if (__a != __s.get_allocator()) { - const_iterator __e = cend(); - while (!__s.empty()) - insert(__e, std::move(__s.__tree_.remove(__s.begin())->__get_value())); - } -} - -# endif // _LIBCPP_CXX03_LANG - template <class _Key, class _Compare, class _Allocator> inline _LIBCPP_HIDE_FROM_ABI bool operator==(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) { @@ -1128,13 +1113,10 @@ public: # ifndef _LIBCPP_CXX03_LANG _LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s) = default; - _LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s, const allocator_type& __a); + _LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s, const allocator_type& __a) : __tree_(std::move(__s.__tree_), __a) {} # endif // _LIBCPP_CXX03_LANG _LIBCPP_HIDE_FROM_ABI explicit multiset(const allocator_type& __a) : __tree_(__a) {} - _LIBCPP_HIDE_FROM_ABI multiset(const multiset& __s, const allocator_type& __a) - : __tree_(__s.__tree_.value_comp(), __a) { - insert(__s.begin(), __s.end()); - } + _LIBCPP_HIDE_FROM_ABI multiset(const multiset& __s, const allocator_type& __a) : __tree_(__s.__tree_, __a) {} # ifndef _LIBCPP_CXX03_LANG _LIBCPP_HIDE_FROM_ABI multiset(initializer_list<value_type> __il, const value_compare& __comp = value_compare()) @@ -1407,20 +1389,6 @@ template <class _Key, class _Allocator, class = enable_if_t<__is_allocator_v<_Al multiset(initializer_list<_Key>, _Allocator) -> multiset<_Key, less<_Key>, _Allocator>; # endif -# ifndef _LIBCPP_CXX03_LANG - -template <class _Key, class _Compare, class _Allocator> -multiset<_Key, _Compare, _Allocator>::multiset(multiset&& __s, const allocator_type& __a) - : __tree_(std::move(__s.__tree_), __a) { - if (__a != __s.get_allocator()) { - const_iterator __e = cend(); - while (!__s.empty()) - insert(__e, std::move(__s.__tree_.remove(__s.begin())->__get_value())); - } -} - -# endif // _LIBCPP_CXX03_LANG - template <class _Key, class _Compare, class _Allocator> inline _LIBCPP_HIDE_FROM_ABI bool operator==(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) { diff --git a/libcxx/include/span b/libcxx/include/span index 3d4f9e4..1911bad 100644 --- a/libcxx/include/span +++ b/libcxx/include/span @@ -310,30 +310,32 @@ public: } template <size_t _Count> - _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept { static_assert(_Count <= _Extent, "span<T, N>::first<Count>(): Count out of range"); return span<element_type, _Count>{data(), _Count}; } template <size_t _Count> - _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept { static_assert(_Count <= _Extent, "span<T, N>::last<Count>(): Count out of range"); return span<element_type, _Count>{data() + size() - _Count, _Count}; } - _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> + first(size_type __count) const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::first(count): count out of range"); return {data(), __count}; } - _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> + last(size_type __count) const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::last(count): count out of range"); return {data() + size() - __count, __count}; } template <size_t _Offset, size_t _Count = dynamic_extent> - _LIBCPP_HIDE_FROM_ABI constexpr auto - subspan() const noexcept -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto subspan() const noexcept + -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> { static_assert(_Offset <= _Extent, "span<T, N>::subspan<Offset, Count>(): Offset out of range"); static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, "span<T, N>::subspan<Offset, Count>(): Offset + Count out of range"); @@ -342,7 +344,7 @@ public: return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; } - _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T, N>::subspan(offset, count): offset out of range"); if (__count == dynamic_extent) @@ -352,52 +354,58 @@ public: return {data() + __offset, __count}; } - _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return _Extent; } - _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return _Extent; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { + return _Extent * sizeof(element_type); + } [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return _Extent == 0; } - _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T, N>::operator[](index): index out of range"); return __data_[__idx]; } # if _LIBCPP_STD_VER >= 26 - _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const { if (__index >= size()) std::__throw_out_of_range("span"); return __data_[__index]; } # endif - _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::front() on empty span"); return __data_[0]; } - _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::back() on empty span"); return __data_[size() - 1]; } - _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } // [span.iter], span iterator support - _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { # ifdef _LIBCPP_ABI_BOUNDED_ITERATORS return std::__make_bounded_iter(data(), data(), data() + size()); # else return iterator(data()); # endif } - _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { # ifdef _LIBCPP_ABI_BOUNDED_ITERATORS return std::__make_bounded_iter(data() + size(), data(), data() + size()); # else return iterator(data() + size()); # endif } - _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { + return reverse_iterator(end()); + } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { + return reverse_iterator(begin()); + } _LIBCPP_HIDE_FROM_ABI span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept { return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte*>(data()), size_bytes()}; @@ -478,36 +486,38 @@ public: : __data_{__other.data()}, __size_{__other.size()} {} template <size_t _Count> - _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::first<Count>(): Count out of range"); return span<element_type, _Count>{data(), _Count}; } template <size_t _Count> - _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::last<Count>(): Count out of range"); return span<element_type, _Count>{data() + size() - _Count, _Count}; } - _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> + first(size_type __count) const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::first(count): count out of range"); return {data(), __count}; } - _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> + last(size_type __count) const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::last(count): count out of range"); return {data() + size() - __count, __count}; } template <size_t _Offset, size_t _Count = dynamic_extent> - _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> subspan() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> subspan() const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range"); _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count == dynamic_extent || _Count <= size() - _Offset, "span<T>::subspan<Offset, Count>(): Offset + Count out of range"); return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; } - constexpr span<element_type, dynamic_extent> _LIBCPP_HIDE_FROM_ABI + [[nodiscard]] constexpr span<element_type, dynamic_extent> _LIBCPP_HIDE_FROM_ABI subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T>::subspan(offset, count): offset out of range"); if (__count == dynamic_extent) @@ -517,52 +527,58 @@ public: return {data() + __offset, __count}; } - _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return __size_; } - _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return __size_ * sizeof(element_type); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return __size_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { + return __size_ * sizeof(element_type); + } [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return __size_ == 0; } - _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T>::operator[](index): index out of range"); return __data_[__idx]; } # if _LIBCPP_STD_VER >= 26 - _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const { if (__index >= size()) std::__throw_out_of_range("span"); return __data_[__index]; } # endif - _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::front() on empty span"); return __data_[0]; } - _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::back() on empty span"); return __data_[size() - 1]; } - _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } // [span.iter], span iterator support - _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { # ifdef _LIBCPP_ABI_BOUNDED_ITERATORS return std::__make_bounded_iter(data(), data(), data() + size()); # else return iterator(data()); # endif } - _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { # ifdef _LIBCPP_ABI_BOUNDED_ITERATORS return std::__make_bounded_iter(data() + size(), data(), data() + size()); # else return iterator(data() + size()); # endif } - _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { + return reverse_iterator(end()); + } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { + return reverse_iterator(begin()); + } _LIBCPP_HIDE_FROM_ABI span<const byte, dynamic_extent> __as_bytes() const noexcept { return {reinterpret_cast<const byte*>(data()), size_bytes()}; @@ -585,13 +601,13 @@ inline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true; // as_bytes & as_writable_bytes template <class _Tp, size_t _Extent> -_LIBCPP_HIDE_FROM_ABI auto as_bytes(span<_Tp, _Extent> __s) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto as_bytes(span<_Tp, _Extent> __s) noexcept { return __s.__as_bytes(); } template <class _Tp, size_t _Extent> requires(!is_const_v<_Tp>) -_LIBCPP_HIDE_FROM_ABI auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept { return __s.__as_writable_bytes(); } diff --git a/libcxx/include/stack b/libcxx/include/stack index a2f285c..537b822 100644 --- a/libcxx/include/stack +++ b/libcxx/include/stack @@ -235,9 +235,9 @@ public: # endif [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const { return c.empty(); } - _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); } - _LIBCPP_HIDE_FROM_ABI reference top() { return c.back(); } - _LIBCPP_HIDE_FROM_ABI const_reference top() const { return c.back(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const { return c.size(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference top() { return c.back(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference top() const { return c.back(); } _LIBCPP_HIDE_FROM_ABI void push(const value_type& __v) { c.push_back(__v); } # ifndef _LIBCPP_CXX03_LANG diff --git a/libcxx/include/stdbool.h b/libcxx/include/stdbool.h deleted file mode 100644 index 768d082..0000000 --- a/libcxx/include/stdbool.h +++ /dev/null @@ -1,44 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP_STDBOOL_H -#define _LIBCPP_STDBOOL_H - -/* - stdbool.h synopsis - -Macros: - - __bool_true_false_are_defined - -*/ - -#if defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) -# include <__cxx03/__config> -#else -# include <__config> -#endif - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if __has_include_next(<stdbool.h>) -# include_next <stdbool.h> -#endif - -#ifdef __cplusplus -# undef bool -# undef true -# undef false -# undef __bool_true_false_are_defined -# define __bool_true_false_are_defined 1 -#endif - -#endif // _LIBCPP_STDBOOL_H diff --git a/libcxx/include/stdexcept b/libcxx/include/stdexcept index 85e1162..d01de5c 100644 --- a/libcxx/include/stdexcept +++ b/libcxx/include/stdexcept @@ -91,7 +91,7 @@ public: ~logic_error() _NOEXCEPT override; - const char* what() const _NOEXCEPT override; + [[__nodiscard__]] const char* what() const _NOEXCEPT override; # else public: @@ -115,7 +115,7 @@ public: ~runtime_error() _NOEXCEPT override; - const char* what() const _NOEXCEPT override; + [[__nodiscard__]] const char* what() const _NOEXCEPT override; # else public: diff --git a/libcxx/include/string b/libcxx/include/string index ede4246..2b3ba6d 100644 --- a/libcxx/include/string +++ b/libcxx/include/string @@ -632,7 +632,6 @@ basic_string<char32_t> operator""s( const char32_t *str, size_t len ); # include <__type_traits/is_generic_transparent_comparator.h> # include <__type_traits/is_nothrow_assignable.h> # include <__type_traits/is_nothrow_constructible.h> -# include <__type_traits/is_replaceable.h> # include <__type_traits/is_same.h> # include <__type_traits/is_standard_layout.h> # include <__type_traits/is_trivially_constructible.h> @@ -757,9 +756,6 @@ public: // external memory. In such cases, the destructor is responsible for unpoisoning // the memory to avoid triggering false positives. // Therefore it's crucial to ensure the destructor is called. - // - // However, it is replaceable since implementing move-assignment as a destroy + move-construct - // will maintain the right ASAN state. using __trivially_relocatable = void; # else using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t< @@ -767,10 +763,6 @@ public: basic_string, void>; # endif - using __replaceable _LIBCPP_NODEBUG = - __conditional_t<__is_replaceable_v<pointer> && __container_allocator_is_replaceable<__alloc_traits>::value, - basic_string, - void>; # if __has_feature(address_sanitizer) && _LIBCPP_INSTRUMENTED_WITH_ASAN _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pointer __asan_volatile_wrapper(pointer const& __ptr) const { @@ -1253,45 +1245,55 @@ public: # endif _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(value_type __c); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() _NOEXCEPT { return __make_iterator(__get_pointer()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator begin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator begin() const _NOEXCEPT { return __make_const_iterator(__get_pointer()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() _NOEXCEPT { return __make_iterator(__get_pointer() + size()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator end() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator end() const _NOEXCEPT { return __make_const_iterator(__get_pointer() + size()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rbegin() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator + rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rend() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rend() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cbegin() const _NOEXCEPT { return begin(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cend() const _NOEXCEPT { return end(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cbegin() const _NOEXCEPT { + return begin(); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cend() const _NOEXCEPT { + return end(); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator + crbegin() const _NOEXCEPT { return rbegin(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crend() const _NOEXCEPT { return rend(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crend() const _NOEXCEPT { + return rend(); + } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type size() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type size() const _NOEXCEPT { return __is_long() ? __get_long_size() : __get_short_size(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type length() const _NOEXCEPT { return size(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type length() const _NOEXCEPT { + return size(); + } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type max_size() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type max_size() const _NOEXCEPT { if (size_type __m = __alloc_traits::max_size(__alloc_); __m <= std::numeric_limits<size_type>::max() / 2) { size_type __res = __m - __alignment; @@ -1309,7 +1311,7 @@ public: } } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type capacity() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type capacity() const _NOEXCEPT { return (__is_long() ? __get_long_cap() : static_cast<size_type>(__min_cap)) - 1; } @@ -1344,7 +1346,8 @@ public: return size() == 0; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __pos) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference + operator[](size_type __pos) const _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds"); if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) { return *(__get_long_pointer() + __pos); @@ -1352,7 +1355,8 @@ public: return *(data() + __pos); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __pos) _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference + operator[](size_type __pos) _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds"); if (__builtin_constant_p(__pos) && !__fits_in_sso(__pos)) { return *(__get_long_pointer() + __pos); @@ -1360,8 +1364,8 @@ public: return *(__get_pointer() + __pos); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const; - _LIBCPP_CONSTEXPR_SINCE_CXX20 reference at(size_type __n); + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const; + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 reference at(size_type __n); _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(const basic_string& __str) { return append(__str); @@ -1473,22 +1477,22 @@ public: _LIBCPP_CONSTEXPR_SINCE_CXX20 void push_back(value_type __c); _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back(); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty"); return *__get_pointer(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty"); return *data(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty"); return *(__get_pointer() + size() - 1); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty"); return *(data() + size() - 1); } @@ -1761,16 +1765,16 @@ public: _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const; # if _LIBCPP_STD_VER <= 20 - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string - substr(size_type __pos = 0, size_type __n = npos) const { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string substr(size_type __pos = 0, size_type __n = npos) const { return basic_string(*this, __pos, __n); } # else - _LIBCPP_HIDE_FROM_ABI constexpr basic_string substr(size_type __pos = 0, size_type __n = npos) const& { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr basic_string substr(size_type __pos = 0, size_type __n = npos) const& { return basic_string(*this, __pos, __n); } - _LIBCPP_HIDE_FROM_ABI constexpr basic_string substr(size_type __pos = 0, size_type __n = npos) && { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr basic_string substr(size_type __pos = 0, size_type __n = npos) && { return basic_string(std::move(*this), __pos, __n); } # endif @@ -1790,231 +1794,238 @@ public: // [string.ops] // ------------ - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const value_type* c_str() const _NOEXCEPT { return data(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const value_type* data() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const value_type* c_str() const _NOEXCEPT { + return data(); + } + + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const value_type* data() const _NOEXCEPT { return std::__to_address(__get_pointer()); } # if _LIBCPP_STD_VER >= 17 - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 value_type* data() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 value_type* data() _NOEXCEPT { return std::__to_address(__get_pointer()); } # endif - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator_type get_allocator() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator_type get_allocator() const _NOEXCEPT { return __alloc_; } // find - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT { return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __str.data(), __pos, __str.size()); } template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT { __self_view __sv = __t; return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size()); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find(): received nullptr"); return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT { _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find(): received nullptr"); return std::__str_find<value_type, size_type, traits_type, npos>( data(), size(), __s, __pos, traits_type::length(__s)); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT { return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); } // rfind - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT { return std::__str_rfind<value_type, size_type, traits_type, npos>( data(), size(), __str.data(), __pos, __str.size()); } template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT { __self_view __sv = __t; return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size()); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::rfind(): received nullptr"); return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT { _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::rfind(): received nullptr"); return std::__str_rfind<value_type, size_type, traits_type, npos>( data(), size(), __s, __pos, traits_type::length(__s)); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT { return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); } // find_first_of - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT { return std::__str_find_first_of<value_type, size_type, traits_type, npos>( data(), size(), __str.data(), __pos, __str.size()); } template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT { __self_view __sv = __t; return std::__str_find_first_of<value_type, size_type, traits_type, npos>( data(), size(), __sv.data(), __pos, __sv.size()); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr"); return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_first_of(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT { _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_of(): received nullptr"); return std::__str_find_first_of<value_type, size_type, traits_type, npos>( data(), size(), __s, __pos, traits_type::length(__s)); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT { return find(__c, __pos); } // find_last_of - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT { return std::__str_find_last_of<value_type, size_type, traits_type, npos>( data(), size(), __str.data(), __pos, __str.size()); } template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT { __self_view __sv = __t; return std::__str_find_last_of<value_type, size_type, traits_type, npos>( data(), size(), __sv.data(), __pos, __sv.size()); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr"); return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_last_of(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT { _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_of(): received nullptr"); return std::__str_find_last_of<value_type, size_type, traits_type, npos>( data(), size(), __s, __pos, traits_type::length(__s)); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT { return rfind(__c, __pos); } // find_first_not_of - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT { return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( data(), size(), __str.data(), __pos, __str.size()); } template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_first_not_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT { __self_view __sv = __t; return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( data(), size(), __sv.data(), __pos, __sv.size()); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr"); return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_first_not_of(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT { _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_first_not_of(): received nullptr"); return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( data(), size(), __s, __pos, traits_type::length(__s)); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT { return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); } // find_last_not_of - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT { return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( data(), size(), __str.data(), __pos, __str.size()); } template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT { __self_view __sv = __t; return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( data(), size(), __sv.data(), __pos, __sv.size()); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr"); return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_last_not_of(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT { _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::find_last_not_of(): received nullptr"); return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( data(), size(), __s, __pos, traits_type::length(__s)); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT { return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); } // compare - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const basic_string& __str) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int + compare(const basic_string& __str) const _NOEXCEPT { return compare(__self_view(__str)); } template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const _Tp& __t) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const _Tp& __t) const _NOEXCEPT { __self_view __sv = __t; size_t __lhs_sz = size(); size_t __rhs_sz = __sv.size(); @@ -2029,18 +2040,18 @@ public: } template <class _Tp, __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp>, int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(size_type __pos1, size_type __n1, const _Tp& __t) const { __self_view __sv = __t; return compare(__pos1, __n1, __sv.data(), __sv.size()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(size_type __pos1, size_type __n1, const basic_string& __str) const { return compare(__pos1, __n1, __str.data(), __str.size()); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 int + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos) const { return compare(__pos1, __n1, __self_view(__str), __pos2, __n2); } @@ -2049,53 +2060,56 @@ public: __enable_if_t<__can_be_converted_to_string_view_v<_CharT, _Traits, _Tp> && !is_same<__remove_cvref_t<_Tp>, basic_string>::value, int> = 0> - inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int + [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos) const { __self_view __sv = __t; return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 int + compare(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const _NOEXCEPT { _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr"); return compare(0, npos, __s, traits_type::length(__s)); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 int + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(size_type __pos1, size_type __n1, const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const { _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string::compare(): received nullptr"); return compare(__pos1, __n1, __s, traits_type::length(__s)); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 int + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const _LIBCPP_DIAGNOSE_NULLPTR_IF(__n2 != 0 && __s == nullptr, " if n2 is not zero"); // starts_with # if _LIBCPP_STD_VER >= 20 - constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(__self_view __sv) const noexcept { + [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(__self_view __sv) const noexcept { return __self_view(typename __self_view::__assume_valid(), data(), size()).starts_with(__sv); } - constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept { + [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept { return !empty() && _Traits::eq(front(), __c); } - constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept { + [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool + starts_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept { return starts_with(__self_view(__s)); } // ends_with - constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(__self_view __sv) const noexcept { + [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(__self_view __sv) const noexcept { return __self_view(typename __self_view::__assume_valid(), data(), size()).ends_with(__sv); } - constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept { + [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept { return !empty() && _Traits::eq(back(), __c); } - constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept { + [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool + ends_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept { return ends_with(__self_view(__s)); } # endif @@ -2103,15 +2117,16 @@ public: // contains # if _LIBCPP_STD_VER >= 23 - constexpr _LIBCPP_HIDE_FROM_ABI bool contains(__self_view __sv) const noexcept { + [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(__self_view __sv) const noexcept { return __self_view(typename __self_view::__assume_valid(), data(), size()).contains(__sv); } - constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept { + [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept { return __self_view(typename __self_view::__assume_valid(), data(), size()).contains(__c); } - constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const { + [[__nodiscard__]] constexpr _LIBCPP_HIDE_FROM_ABI bool + contains(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const { return __self_view(typename __self_view::__assume_valid(), data(), size()).contains(__s); } # endif @@ -2258,7 +2273,9 @@ private: // Allocate a buffer of __capacity size with __alloc and return it _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 __long __allocate_long_buffer(_Allocator& __alloc, size_type __capacity) { - auto __buffer = std::__allocate_at_least(__alloc, __recommend(__capacity) + 1); + _LIBCPP_ASSERT_INTERNAL(!__fits_in_sso(__capacity), + "Trying to allocate long buffer for a capacity what would fit into the small buffer"); + auto __buffer = std::__allocate_at_least(__alloc, __align_allocation_size(__capacity)); if (__libcpp_is_constant_evaluated()) { for (size_type __i = 0; __i != __buffer.count; ++__i) @@ -2350,19 +2367,36 @@ private: return (__s + (__a - 1)) & ~(__a - 1); } enum { __alignment = 8 }; - static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __s) _NOEXCEPT { - if (__s < __min_cap) { - return static_cast<size_type>(__min_cap) - 1; - } + + // This makes sure that we're using a capacity with some extra alignment, since allocators almost always over-align + // the allocations anyways, improving memory usage. More importantly, this ensures that the lowest bit is never set + // if __endian_factor == 2, allowing us to store whether we're in the long string inside the lowest bit. + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + __align_allocation_size(size_type __size) _NOEXCEPT { + _LIBCPP_ASSERT_INTERNAL( + !__fits_in_sso(__size), "Trying to align allocation of a size which would fit into the SSO"); const size_type __boundary = sizeof(value_type) < __alignment ? __alignment / sizeof(value_type) : __endian_factor; - size_type __guess = __align_it<__boundary>(__s + 1) - 1; - if (__guess == __min_cap) + size_type __guess = __align_it<__boundary>(__size + 1); + if (__guess == __min_cap + 1) __guess += __endian_factor; - _LIBCPP_ASSERT_INTERNAL(__guess >= __s, "recommendation is below the requested size"); + _LIBCPP_ASSERT_INTERNAL(__guess >= __size, "aligned allocation size is below the requested size"); return __guess; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + __get_amortized_growth_capacity(size_type __required_capacity) { + size_type __max_size = max_size(); + if (__required_capacity > __max_size) + __throw_length_error(); + size_type __current_cap = capacity(); + _LIBCPP_ASSERT_INTERNAL( + __current_cap < __required_capacity, "Trying to grow string even though there is enough capacity already?"); + if (__current_cap > __max_size / 2 - __alignment) + return __max_size; + return std::max(__required_capacity, 2 * __current_cap); + } + inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(const value_type* __s, size_type __sz); inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(size_type __n, value_type __c); @@ -2693,15 +2727,10 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__ size_type __n_del, size_type __n_add, const value_type* __p_new_stuff) { - size_type __ms = max_size(); - if (__delta_cap > __ms - __old_cap) - __throw_length_error(); + __long __buffer = __allocate_long_buffer(__alloc_, __get_amortized_growth_capacity(__old_cap + __delta_cap)); pointer __old_p = __get_pointer(); - size_type __cap = - __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms; __annotate_delete(); - auto __guard = std::__make_scope_guard(__annotate_new_size(*this)); - __long __buffer = __allocate_long_buffer(__alloc_, __cap); + auto __guard = std::__make_scope_guard(__annotate_new_size(*this)); if (__n_copy != 0) traits_type::copy(std::__to_address(__buffer.__data_), std::__to_address(__old_p), __n_copy); if (__n_add != 0) @@ -2731,13 +2760,8 @@ _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Trait size_type __n_copy, size_type __n_del, size_type __n_add) { - size_type __ms = max_size(); - if (__delta_cap > __ms - __old_cap) - this->__throw_length_error(); + __long __buffer = __allocate_long_buffer(__alloc_, __get_amortized_growth_capacity(__old_cap + __delta_cap)); pointer __old_p = __get_pointer(); - size_type __cap = - __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms; - __long __buffer = __allocate_long_buffer(__alloc_, __cap); if (__n_copy != 0) traits_type::copy(std::__to_address(__buffer.__data_), std::__to_address(__old_p), __n_copy); size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; @@ -3402,18 +3426,15 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::re template <class _CharT, class _Traits, class _Allocator> inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT { - size_type __target_capacity = __recommend(size()); - if (__target_capacity == capacity()) + if (!__is_long()) return; - _LIBCPP_ASSERT_INTERNAL(__is_long(), "Trying to shrink small string"); - - // We're a long string and we're shrinking into the small buffer. const auto __ptr = __get_long_pointer(); const auto __size = __get_long_size(); const auto __cap = __get_long_cap(); - if (__fits_in_sso(__target_capacity)) { + // We're a long string and we're shrinking into the small buffer. + if (__fits_in_sso(__size)) { __annotation_guard __g(*this); __set_short_size(__size); traits_type::copy(std::__to_address(__get_short_pointer()), std::__to_address(__ptr), __size + 1); @@ -3421,6 +3442,9 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat return; } + if (__align_allocation_size(__size) == __cap) + return; + # if _LIBCPP_HAS_EXCEPTIONS try { # endif // _LIBCPP_HAS_EXCEPTIONS @@ -3827,46 +3851,52 @@ swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Tra __lhs.swap(__rhs); } -_LIBCPP_EXPORTED_FROM_ABI int stoi(const string& __str, size_t* __idx = nullptr, int __base = 10); -_LIBCPP_EXPORTED_FROM_ABI long stol(const string& __str, size_t* __idx = nullptr, int __base = 10); -_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const string& __str, size_t* __idx = nullptr, int __base = 10); -_LIBCPP_EXPORTED_FROM_ABI long long stoll(const string& __str, size_t* __idx = nullptr, int __base = 10); -_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10); - -_LIBCPP_EXPORTED_FROM_ABI float stof(const string& __str, size_t* __idx = nullptr); -_LIBCPP_EXPORTED_FROM_ABI double stod(const string& __str, size_t* __idx = nullptr); -_LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr); - -_LIBCPP_EXPORTED_FROM_ABI string to_string(int __val); -_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val); -_LIBCPP_EXPORTED_FROM_ABI string to_string(long __val); -_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val); -_LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val); -_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val); -_LIBCPP_EXPORTED_FROM_ABI string to_string(float __val); -_LIBCPP_EXPORTED_FROM_ABI string to_string(double __val); -_LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI int stoi(const string& __str, size_t* __idx = nullptr, int __base = 10); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unsigned long +stoul(const string& __str, size_t* __idx = nullptr, int __base = 10); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long stol(const string& __str, size_t* __idx = nullptr, int __base = 10); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long long +stoll(const string& __str, size_t* __idx = nullptr, int __base = 10); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unsigned long long +stoull(const string& __str, size_t* __idx = nullptr, int __base = 10); + +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI float stof(const string& __str, size_t* __idx = nullptr); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI double stod(const string& __str, size_t* __idx = nullptr); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr); + +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(int __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(float __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(double __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val); # if _LIBCPP_HAS_WIDE_CHARACTERS -_LIBCPP_EXPORTED_FROM_ABI int stoi(const wstring& __str, size_t* __idx = nullptr, int __base = 10); -_LIBCPP_EXPORTED_FROM_ABI long stol(const wstring& __str, size_t* __idx = nullptr, int __base = 10); -_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const wstring& __str, size_t* __idx = nullptr, int __base = 10); -_LIBCPP_EXPORTED_FROM_ABI long long stoll(const wstring& __str, size_t* __idx = nullptr, int __base = 10); -_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10); - -_LIBCPP_EXPORTED_FROM_ABI float stof(const wstring& __str, size_t* __idx = nullptr); -_LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr); -_LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr); - -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val); -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val); -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val); -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val); -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val); -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val); -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val); -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val); -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI int stoi(const wstring& __str, size_t* __idx = nullptr, int __base = 10); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long stol(const wstring& __str, size_t* __idx = nullptr, int __base = 10); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unsigned long +stoul(const wstring& __str, size_t* __idx = nullptr, int __base = 10); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long long +stoll(const wstring& __str, size_t* __idx = nullptr, int __base = 10); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unsigned long long +stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10); + +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI float stof(const wstring& __str, size_t* __idx = nullptr); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr); + +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val); # endif // _LIBCPP_HAS_WIDE_CHARACTERS template <class _CharT, class _Traits, class _Allocator> @@ -3875,7 +3905,7 @@ _LIBCPP_TEMPLATE_DATA_VIS const typename basic_string<_CharT, _Traits, _Allocato template <class _CharT, class _Allocator> struct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> { - _LIBCPP_HIDE_FROM_ABI size_t + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT { return std::__do_string_hash(__val.data(), __val.data() + __val.size()); } @@ -3946,30 +3976,31 @@ erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, _Predicate __pred) { // Literal suffixes for basic_string [basic.string.literals] inline namespace literals { inline namespace string_literals { -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char> +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char> operator""s(const char* __str, size_t __len) { return basic_string<char>(__str, __len); } # if _LIBCPP_HAS_WIDE_CHARACTERS -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<wchar_t> -operator""s(const wchar_t* __str, size_t __len) { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<wchar_t> operator""s(const wchar_t* __str, size_t __len) { return basic_string<wchar_t>(__str, __len); } # endif # if _LIBCPP_HAS_CHAR8_T -inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string<char8_t> operator""s(const char8_t* __str, size_t __len) { +[[__nodiscard__]] inline + _LIBCPP_HIDE_FROM_ABI constexpr basic_string<char8_t> operator""s(const char8_t* __str, size_t __len) { return basic_string<char8_t>(__str, __len); } # endif -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char16_t> -operator""s(const char16_t* __str, size_t __len) { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char16_t> operator""s(const char16_t* __str, size_t __len) { return basic_string<char16_t>(__str, __len); } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char32_t> +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char32_t> operator""s(const char32_t* __str, size_t __len) { return basic_string<char32_t>(__str, __len); } diff --git a/libcxx/include/string_view b/libcxx/include/string_view index 5ecaa3d..5dd04a9 100644 --- a/libcxx/include/string_view +++ b/libcxx/include/string_view @@ -362,11 +362,11 @@ public: # endif // [string.view.iterators], iterators - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return cbegin(); } + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return cbegin(); } - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return cend(); } + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return cend(); } - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { # ifdef _LIBCPP_ABI_BOUNDED_ITERATORS return std::__make_bounded_iter(data(), data(), data() + size()); # else @@ -374,7 +374,7 @@ public: # endif } - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { # ifdef _LIBCPP_ABI_BOUNDED_ITERATORS return std::__make_bounded_iter(data() + size(), data(), data() + size()); # else @@ -382,51 +382,54 @@ public: # endif } - _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator + rbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); } - _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); } - _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator + crbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); } - _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); } // [string.view.capacity], capacity - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size_; } + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size_; } - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type length() const _NOEXCEPT { return __size_; } + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type length() const _NOEXCEPT { return __size_; } - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return numeric_limits<size_type>::max() / sizeof(value_type); } [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return __size_ == 0; } // [string.view.access], element access - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __pos) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference + operator[](size_type __pos) const _NOEXCEPT { return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos < size(), "string_view[] index out of bounds"), __data_[__pos]; } - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __pos) const { + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __pos) const { return __pos >= size() ? (__throw_out_of_range("string_view::at"), __data_[0]) : __data_[__pos]; } - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT { return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::front(): string is empty"), __data_[0]; } - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT { return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::back(): string is empty"), __data_[__size_ - 1]; } - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_pointer data() const _NOEXCEPT { return __data_; } + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_pointer data() const _NOEXCEPT { return __data_; } // [string.view.modifiers], modifiers: _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI void remove_prefix(size_type __n) _NOEXCEPT { @@ -459,7 +462,8 @@ public: return __rlen; } - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view substr(size_type __pos = 0, size_type __n = npos) const { + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view + substr(size_type __pos = 0, size_type __n = npos) const { // Use the `__assume_valid` form of the constructor to avoid an unnecessary check. Any substring of a view is a // valid view. In particular, `size()` is known to be smaller than `numeric_limits<difference_type>::max()`, so the // new size is also smaller. See also https://llvm.org/PR91634. @@ -474,7 +478,7 @@ public: } # endif - _LIBCPP_CONSTEXPR_SINCE_CXX14 int compare(basic_string_view __sv) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 int compare(basic_string_view __sv) const _NOEXCEPT { size_type __rlen = std::min(size(), __sv.size()); int __retval = _Traits::compare(data(), __sv.data(), __rlen); if (__retval == 0) // first __rlen chars matched @@ -482,50 +486,51 @@ public: return __retval; } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const { return substr(__pos1, __n1).compare(__sv); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI 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_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int compare(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s) const _NOEXCEPT { return compare(basic_string_view(__s)); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int compare(size_type __pos1, size_type __n1, const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s) const { return substr(__pos1, __n1).compare(basic_string_view(__s)); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const _LIBCPP_DIAGNOSE_NULLPTR_IF(__n2 != 0 && __s == nullptr, " if n2 is not zero") { return substr(__pos1, __n1).compare(basic_string_view(__s, __n2)); } // find - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT { return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s.data(), __pos, __s.size()); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find(_CharT __c, size_type __pos = 0) const _NOEXCEPT { return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find(): received nullptr"); return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT { _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find(): received nullptr"); return std::__str_find<value_type, size_type, traits_type, npos>( @@ -533,24 +538,24 @@ public: } // rfind - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT { return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s.data(), __pos, __s.size()); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT { return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr"); return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type rfind(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT { _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::rfind(): received nullptr"); return std::__str_rfind<value_type, size_type, traits_type, npos>( @@ -558,25 +563,25 @@ public: } // find_first_of - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT { return std::__str_find_first_of<value_type, size_type, traits_type, npos>( data(), size(), __s.data(), __pos, __s.size()); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT { return find(__c, __pos); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr"); return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find_first_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT { _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_of(): received nullptr"); return std::__str_find_first_of<value_type, size_type, traits_type, npos>( @@ -584,25 +589,25 @@ public: } // find_last_of - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find_last_of(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT { return std::__str_find_last_of<value_type, size_type, traits_type, npos>( data(), size(), __s.data(), __pos, __s.size()); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT { return rfind(__c, __pos); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr"); return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find_last_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT { _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_of(): received nullptr"); return std::__str_find_last_of<value_type, size_type, traits_type, npos>( @@ -610,25 +615,25 @@ public: } // find_first_not_of - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find_first_not_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT { return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( data(), size(), __s.data(), __pos, __s.size()); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find_first_not_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT { return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr"); return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find_first_not_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT { _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_not_of(): received nullptr"); return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( @@ -636,25 +641,25 @@ public: } // find_last_not_of - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find_last_not_of(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT { return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( data(), size(), __s.data(), __pos, __s.size()); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find_last_not_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT { return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr"); return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); } - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find_last_not_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT { _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_not_of(): received nullptr"); return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( @@ -662,37 +667,43 @@ public: } # if _LIBCPP_STD_VER >= 20 - constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(basic_string_view __s) const noexcept { + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(basic_string_view __s) const noexcept { return size() >= __s.size() && compare(0, __s.size(), __s) == 0; } - constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept { + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept { return !empty() && _Traits::eq(front(), __c); } - constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept { + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool + starts_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept { return starts_with(basic_string_view(__s)); } - constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(basic_string_view __s) const noexcept { + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(basic_string_view __s) const noexcept { return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0; } - constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept { + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept { return !empty() && _Traits::eq(back(), __c); } - constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept { + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool + ends_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept { return ends_with(basic_string_view(__s)); } # endif # if _LIBCPP_STD_VER >= 23 - constexpr _LIBCPP_HIDE_FROM_ABI bool contains(basic_string_view __sv) const noexcept { return find(__sv) != npos; } + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(basic_string_view __sv) const noexcept { + return find(__sv) != npos; + } - constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept { return find(__c) != npos; } + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept { + return find(__c) != npos; + } - constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const { + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const { return find(__s) != npos; } # endif @@ -897,7 +908,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Trai // [string.view.hash] template <class _CharT> struct __string_view_hash : public __unary_function<basic_string_view<_CharT, char_traits<_CharT> >, size_t> { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t + operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT { return std::__do_string_hash(__val.data(), __val.data() + __val.size()); } }; @@ -924,30 +936,31 @@ struct hash<basic_string_view<wchar_t, char_traits<wchar_t> > > : __string_view_ # if _LIBCPP_STD_VER >= 14 inline namespace literals { inline namespace string_view_literals { -inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char> operator""sv(const char* __str, size_t __len) noexcept { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char> +operator""sv(const char* __str, size_t __len) noexcept { return basic_string_view<char>(__str, __len); } # if _LIBCPP_HAS_WIDE_CHARACTERS -inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<wchar_t> +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<wchar_t> operator""sv(const wchar_t* __str, size_t __len) noexcept { return basic_string_view<wchar_t>(__str, __len); } # endif # if _LIBCPP_HAS_CHAR8_T -inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char8_t> +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char8_t> operator""sv(const char8_t* __str, size_t __len) noexcept { return basic_string_view<char8_t>(__str, __len); } # endif -inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char16_t> +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char16_t> operator""sv(const char16_t* __str, size_t __len) noexcept { return basic_string_view<char16_t>(__str, __len); } -inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char32_t> +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char32_t> operator""sv(const char32_t* __str, size_t __len) noexcept { return basic_string_view<char32_t>(__str, __len); } diff --git a/libcxx/include/tuple b/libcxx/include/tuple index 0cfcd9a..670b90f 100644 --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -252,7 +252,6 @@ template <class... Types> # include <__type_traits/is_nothrow_assignable.h> # include <__type_traits/is_nothrow_constructible.h> # include <__type_traits/is_reference.h> -# include <__type_traits/is_replaceable.h> # include <__type_traits/is_same.h> # include <__type_traits/is_swappable.h> # include <__type_traits/is_trivially_relocatable.h> @@ -577,7 +576,7 @@ __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __type_list<_Up.. template <class... _Tp> class _LIBCPP_NO_SPECIALIZATIONS tuple { - typedef __tuple_impl<__make_index_sequence<sizeof...(_Tp)>, _Tp...> _BaseT; + typedef __tuple_impl<__index_sequence_for<_Tp...>, _Tp...> _BaseT; _BaseT __base_; @@ -596,7 +595,6 @@ class _LIBCPP_NO_SPECIALIZATIONS tuple { public: using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t<_And<__libcpp_is_trivially_relocatable<_Tp>...>::value, tuple, void>; - using __replaceable _LIBCPP_NODEBUG = __conditional_t<_And<__is_replaceable<_Tp>...>::value, tuple, void>; // [tuple.cnstr] @@ -860,7 +858,7 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple) noexcept( _And<is_nothrow_copy_assignable<_Tp>...>::value) { - std::__memberwise_copy_assign(*this, __tuple, __make_index_sequence<sizeof...(_Tp)>()); + std::__memberwise_copy_assign(*this, __tuple, __index_sequence_for<_Tp...>()); return *this; } @@ -868,15 +866,14 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(tuple const& __tuple) const requires(_And<is_copy_assignable<const _Tp>...>::value) { - std::__memberwise_copy_assign(*this, __tuple, __make_index_sequence<sizeof...(_Tp)>()); + std::__memberwise_copy_assign(*this, __tuple, __index_sequence_for<_Tp...>()); return *this; } _LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(tuple&& __tuple) const requires(_And<is_assignable<const _Tp&, _Tp>...>::value) { - std::__memberwise_forward_assign( - *this, std::move(__tuple), __type_list<_Tp...>(), __make_index_sequence<sizeof...(_Tp)>()); + std::__memberwise_forward_assign(*this, std::move(__tuple), __type_list<_Tp...>(), __index_sequence_for<_Tp...>()); return *this; } # endif // _LIBCPP_STD_VER >= 23 @@ -884,8 +881,7 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple) noexcept( _And<is_nothrow_move_assignable<_Tp>...>::value) { - std::__memberwise_forward_assign( - *this, std::move(__tuple), __type_list<_Tp...>(), __make_index_sequence<sizeof...(_Tp)>()); + std::__memberwise_forward_assign(*this, std::move(__tuple), __type_list<_Tp...>(), __index_sequence_for<_Tp...>()); return *this; } @@ -895,7 +891,7 @@ public: int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple& operator=(tuple<_Up...> const& __tuple) noexcept(_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value) { - std::__memberwise_copy_assign(*this, __tuple, __make_index_sequence<sizeof...(_Tp)>()); + std::__memberwise_copy_assign(*this, __tuple, __index_sequence_for<_Tp...>()); return *this; } @@ -904,8 +900,7 @@ public: int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple& operator=(tuple<_Up...>&& __tuple) noexcept(_And<is_nothrow_assignable<_Tp&, _Up>...>::value) { - std::__memberwise_forward_assign( - *this, std::move(__tuple), __type_list<_Up...>(), __make_index_sequence<sizeof...(_Tp)>()); + std::__memberwise_forward_assign(*this, std::move(__tuple), __type_list<_Up...>(), __index_sequence_for<_Tp...>()); return *this; } @@ -914,7 +909,7 @@ public: enable_if_t< _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>, is_assignable<const _Tp&, const _UTypes&>...>::value>* = nullptr> _LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(const tuple<_UTypes...>& __u) const { - std::__memberwise_copy_assign(*this, __u, __make_index_sequence<sizeof...(_Tp)>()); + std::__memberwise_copy_assign(*this, __u, index_sequence_for<_Tp...>()); return *this; } @@ -922,7 +917,7 @@ public: enable_if_t< _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>, is_assignable<const _Tp&, _UTypes>...>::value>* = nullptr> _LIBCPP_HIDE_FROM_ABI constexpr const tuple& operator=(tuple<_UTypes...>&& __u) const { - std::__memberwise_forward_assign(*this, __u, __type_list<_UTypes...>(), __make_index_sequence<sizeof...(_Tp)>()); + std::__memberwise_forward_assign(*this, __u, __type_list<_UTypes...>(), index_sequence_for<_Tp...>()); return *this; } # endif // _LIBCPP_STD_VER >= 23 @@ -988,7 +983,7 @@ public: __enable_if_t< _And< _BoolConstant<_Np == sizeof...(_Tp)>, is_assignable<_Tp&, _Up const&>... >::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple& operator=(array<_Up, _Np> const& __array) noexcept(_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value) { - std::__memberwise_copy_assign(*this, __array, __make_index_sequence<sizeof...(_Tp)>()); + std::__memberwise_copy_assign(*this, __array, __index_sequence_for<_Tp...>()); return *this; } @@ -1000,7 +995,7 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple& operator=(array<_Up, _Np>&& __array) noexcept(_And<is_nothrow_assignable<_Tp&, _Up>...>::value) { std::__memberwise_forward_assign( - *this, std::move(__array), __type_list<_If<true, _Up, _Tp>...>(), __make_index_sequence<sizeof...(_Tp)>()); + *this, std::move(__array), __type_list<_If<true, _Up, _Tp>...>(), __index_sequence_for<_Tp...>()); return *this; } diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index dab0c06..f3e397e 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -550,9 +550,7 @@ namespace std # if _LIBCPP_STD_VER >= 20 # include <__type_traits/common_reference.h> -# include <__type_traits/is_bounded_array.h> # include <__type_traits/is_constant_evaluated.h> -# include <__type_traits/is_unbounded_array.h> # include <__type_traits/type_identity.h> # include <__type_traits/unwrap_ref.h> # endif diff --git a/libcxx/include/variant b/libcxx/include/variant index 8e95858..df587cc 100644 --- a/libcxx/include/variant +++ b/libcxx/include/variant @@ -247,7 +247,6 @@ namespace std { # include <__type_traits/is_nothrow_assignable.h> # include <__type_traits/is_nothrow_constructible.h> # include <__type_traits/is_reference.h> -# include <__type_traits/is_replaceable.h> # include <__type_traits/is_same.h> # include <__type_traits/is_swappable.h> # include <__type_traits/is_trivially_assignable.h> @@ -1172,7 +1171,6 @@ class _LIBCPP_DECLSPEC_EMPTY_BASES _LIBCPP_NO_SPECIALIZATIONS variant public: using __trivially_relocatable _LIBCPP_NODEBUG = conditional_t<_And<__libcpp_is_trivially_relocatable<_Types>...>::value, variant, void>; - using __replaceable _LIBCPP_NODEBUG = conditional_t<_And<__is_replaceable<_Types>...>::value, variant, void>; template <bool _Dummy = true, enable_if_t<__dependent_type<is_default_constructible<__first_type>, _Dummy>::value, int> = 0> diff --git a/libcxx/include/version b/libcxx/include/version index b003060..05532ea 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -187,7 +187,8 @@ __cpp_lib_nonmember_container_access 201411L <array> <deque> __cpp_lib_not_fn 202306L <functional> 201603L // C++17 __cpp_lib_null_iterators 201304L <iterator> -__cpp_lib_optional 202110L <optional> +__cpp_lib_optional 202506L <optional> + 202110L // C++23 202106L // C++20 201606L // C++17 __cpp_lib_optional_range_support 202406L <optional> @@ -594,6 +595,8 @@ __cpp_lib_void_t 201411L <type_traits> # define __cpp_lib_mdspan 202406L # undef __cpp_lib_not_fn # define __cpp_lib_not_fn 202306L +# undef __cpp_lib_optional +# define __cpp_lib_optional 202506L # define __cpp_lib_optional_range_support 202406L # undef __cpp_lib_out_ptr # define __cpp_lib_out_ptr 202311L diff --git a/libcxx/lib/abi/CHANGELOG.TXT b/libcxx/lib/abi/CHANGELOG.TXT index 968dc7a..990c0a6 100644 --- a/libcxx/lib/abi/CHANGELOG.TXT +++ b/libcxx/lib/abi/CHANGELOG.TXT @@ -16,6 +16,20 @@ New entries should be added directly below the "Version" header. Version 22.0 ------------ +* [libc++] Allows any types of size 4 and 8 to use native platform ulock_wait + + This patch added symbols for platform wait functions with the size of the type + + All platforms + ------------- + Symbol added: __ZNSt3__123__atomic_monitor_globalEPKv + Symbol added: __ZNSt3__126__atomic_wait_global_tableEPKvx + Symbol added: __ZNSt3__126__atomic_notify_one_nativeILm8EEEvPKv + Symbol added: __ZNSt3__132__atomic_notify_all_global_tableEPKv + Symbol added: __ZNSt3__120__atomic_wait_nativeILm8EEEvPKvS2_ + Symbol added: __ZNSt3__126__atomic_notify_all_nativeILm8EEEvPKv + Symbol added: __ZNSt3__132__atomic_notify_one_global_tableEPKv + * [libc++] Remove __time_get_storage::{__analyze,init} from the ABI These functions have never been used outside the dylib, so there is no point in exporting them. diff --git a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist index 3a1d895..0910243 100644 --- a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist +++ b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist @@ -534,6 +534,7 @@ {'is_defined': True, 'name': '__ZNKSt3__115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNKSt3__115error_condition7messageEv', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNKSt3__117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNKSt3__117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNKSt3__117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'} @@ -1125,6 +1126,7 @@ {'is_defined': True, 'name': '__ZNSt3__112system_errorD0Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__112system_errorD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__112system_errorD2Ev', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'} @@ -1305,7 +1307,6 @@ {'is_defined': True, 'name': '__ZNSt3__113shared_futureIvED1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'} -{'is_defined': True, 'name': '__ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__114__num_get_base5__srcE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'} @@ -1508,7 +1509,6 @@ {'is_defined': True, 'name': '__ZNSt3__117bad_function_callD0Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__117bad_function_callD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__117bad_function_callD2Ev', 'type': 'FUNC'} -{'is_defined': True, 'name': '__ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__117iostream_categoryEv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'} @@ -1558,6 +1558,7 @@ {'is_defined': True, 'name': '__ZNSt3__119__thread_local_dataEv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__120__atomic_wait_nativeILm8EEEvPKvS2_', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__120__get_collation_nameEPKc', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEEx', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__120__libcpp_atomic_waitEPVKvx', 'type': 'FUNC'} @@ -1571,6 +1572,7 @@ {'is_defined': True, 'name': '__ZNSt3__121recursive_timed_mutexD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__121recursive_timed_mutexD2Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__123__atomic_monitor_globalEPKv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__123__cxx_atomic_notify_allEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'} @@ -1578,9 +1580,14 @@ {'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__126__atomic_notify_all_nativeILm8EEEvPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__126__atomic_notify_one_nativeILm8EEEvPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__126__atomic_wait_global_tableEPKvx', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__13cinE', 'size': 0, 'type': 'OBJECT'} diff --git a/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist index 313de84..881914d 100644 --- a/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist +++ b/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist @@ -170,6 +170,7 @@ {'is_defined': True, 'name': '_ZNKSt6__ndk115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt6__ndk115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt6__ndk115error_condition7messageEv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNKSt6__ndk117bad_function_call4whatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'} @@ -761,6 +762,7 @@ {'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD0Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD2Ev', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt6__ndk113__hash_memoryEPKvj', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'} @@ -941,7 +943,6 @@ {'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvED1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvED2Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvEaSERKS1_', 'type': 'FUNC'} -{'is_defined': True, 'name': '_ZNSt6__ndk113__hash_memoryEPKvj', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZNSt6__ndk114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'} @@ -1144,7 +1145,6 @@ {'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD0Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD2Ev', 'type': 'FUNC'} -{'is_defined': True, 'name': '_ZNKSt6__ndk117bad_function_call4whatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk117iostream_categoryEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'} @@ -1194,6 +1194,7 @@ {'is_defined': True, 'name': '_ZNSt6__ndk119__thread_local_dataEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt6__ndk120__atomic_wait_nativeILj4EEEvPKvS2_', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk120__get_collation_nameEPKc', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEEi', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk120__libcpp_atomic_waitEPVKvi', 'type': 'FUNC'} @@ -1207,6 +1208,7 @@ {'is_defined': True, 'name': '_ZNSt6__ndk121recursive_timed_mutexD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk121recursive_timed_mutexD2Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt6__ndk123__atomic_monitor_globalEPKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk123__cxx_atomic_notify_allEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'} @@ -1214,9 +1216,14 @@ {'is_defined': True, 'name': '_ZNSt6__ndk123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt6__ndk126__atomic_notify_all_nativeILj4EEEvPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt6__ndk126__atomic_notify_one_nativeILj4EEEvPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt6__ndk126__atomic_wait_global_tableEPKvi', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt6__ndk132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt6__ndk132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk134__construct_barrier_algorithm_baseERi', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk13cinE', 'size': 148, 'type': 'OBJECT'} diff --git a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist index 99cde72..bce5dab 100644 --- a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist +++ b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist @@ -96,6 +96,7 @@ {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115__codecvt_utf16IwLb1EE6do_outERPcPKwS5_RS5_S2_S2_S3_', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115__codecvt_utf16IwLb1EE9do_lengthERPcPKcS5_m', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115error_condition7messageEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__118__time_get_storageIcE15__do_date_orderEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__118__time_get_storageIwE15__do_date_orderEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__119__shared_weak_count13__get_deleterERKSt9type_info', 'storage_mapping_class': 'DS', 'type': 'FUNC'} @@ -410,6 +411,7 @@ {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceC2ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} @@ -418,7 +420,6 @@ {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'storage_mapping_class': 'DS', 'type': 'FUNC'} -{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'storage_mapping_class': 'DS', 'type': 'FUNC'} @@ -503,7 +504,6 @@ {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} -{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117iostream_categoryEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'} @@ -559,6 +559,7 @@ {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexC2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__atomic_monitor_globalEPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} @@ -566,7 +567,10 @@ {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__126__atomic_wait_global_tableEPKvi', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_all_global_tableEPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13cinE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'} @@ -1705,7 +1709,10 @@ {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__120__atomic_wait_nativeILm4EEEvPKvS2_', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__122__libcpp_verbose_abortEPKcz', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_all_nativeILm4EEEvPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_one_nativeILm4EEEvPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem16_FilesystemClock9is_steadyE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'} diff --git a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist index 577d6cf..36eb5b8 100644 --- a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist +++ b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist @@ -96,6 +96,7 @@ {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115__codecvt_utf16IwLb1EE6do_outERPcPKwS5_RS5_S2_S2_S3_', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115__codecvt_utf16IwLb1EE9do_lengthERPcPKcS5_m', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__115error_condition7messageEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__118__time_get_storageIcE15__do_date_orderEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__118__time_get_storageIwE15__do_date_orderEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__119__shared_weak_count13__get_deleterERKSt9type_info', 'storage_mapping_class': 'DS', 'type': 'FUNC'} @@ -410,6 +411,7 @@ {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__112system_errorD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceC1ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceC2ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113random_deviceD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} @@ -418,7 +420,6 @@ {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'storage_mapping_class': 'DS', 'type': 'FUNC'} -{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'storage_mapping_class': 'DS', 'type': 'FUNC'} @@ -503,7 +504,6 @@ {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117bad_function_callD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} -{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117iostream_categoryEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'} @@ -559,6 +559,7 @@ {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexC2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__atomic_monitor_globalEPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} @@ -566,7 +567,10 @@ {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__126__atomic_wait_global_tableEPKvl', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_all_global_tableEPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13cinE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'} @@ -1705,7 +1709,10 @@ {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__120__atomic_wait_nativeILm8EEEvPKvS2_', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__122__libcpp_verbose_abortEPKcz', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_all_nativeILm8EEEvPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} +{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_one_nativeILm8EEEvPKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'storage_mapping_class': 'DS', 'type': 'FUNC'} {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem16_FilesystemClock9is_steadyE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'} diff --git a/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist index 1be7d8a..154b7cc 100644 --- a/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist +++ b/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist @@ -170,6 +170,7 @@ {'is_defined': True, 'name': '_ZNKSt6__ndk115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt6__ndk115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt6__ndk115error_condition7messageEv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNKSt6__ndk117bad_function_call4whatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt6__ndk117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'} @@ -761,6 +762,7 @@ {'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD0Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk112system_errorD2Ev', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt6__ndk113__hash_memoryEPKvm', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'} @@ -941,7 +943,6 @@ {'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvED1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvED2Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk113shared_futureIvEaSERKS1_', 'type': 'FUNC'} -{'is_defined': True, 'name': '_ZNSt6__ndk113__hash_memoryEPKvm', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZNSt6__ndk114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'} @@ -1144,7 +1145,6 @@ {'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD0Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk117bad_function_callD2Ev', 'type': 'FUNC'} -{'is_defined': True, 'name': '_ZNKSt6__ndk117bad_function_call4whatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk117iostream_categoryEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'} @@ -1194,6 +1194,7 @@ {'is_defined': True, 'name': '_ZNSt6__ndk119__thread_local_dataEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt6__ndk120__atomic_wait_nativeILm4EEEvPKvS2_', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk120__get_collation_nameEPKc', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEEi', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk120__libcpp_atomic_waitEPVKvi', 'type': 'FUNC'} @@ -1207,6 +1208,7 @@ {'is_defined': True, 'name': '_ZNSt6__ndk121recursive_timed_mutexD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk121recursive_timed_mutexD2Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt6__ndk123__atomic_monitor_globalEPKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk123__cxx_atomic_notify_allEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'} @@ -1214,9 +1216,14 @@ {'is_defined': True, 'name': '_ZNSt6__ndk123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt6__ndk126__atomic_notify_all_nativeILm4EEEvPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt6__ndk126__atomic_notify_one_nativeILm4EEEvPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt6__ndk126__atomic_wait_global_tableEPKvi', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt6__ndk132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt6__ndk132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt6__ndk13cinE', 'size': 280, 'type': 'OBJECT'} diff --git a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist index 40ae625..685d2a4 100644 --- a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist +++ b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist @@ -227,6 +227,7 @@ {'is_defined': True, 'name': '_ZNKSt3__115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt3__115error_condition7messageEv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'} @@ -775,6 +776,7 @@ {'is_defined': True, 'name': '_ZNSt3__112system_errorD0Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__112system_errorD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__112system_errorD2Ev', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'} @@ -955,7 +957,6 @@ {'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'} -{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'} @@ -1158,7 +1159,6 @@ {'is_defined': True, 'name': '_ZNSt3__117bad_function_callD0Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117bad_function_callD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117bad_function_callD2Ev', 'type': 'FUNC'} -{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117iostream_categoryEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'} @@ -1208,6 +1208,7 @@ {'is_defined': True, 'name': '_ZNSt3__119__thread_local_dataEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__120__atomic_wait_nativeILm8EEEvPKvS2_', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__120__get_collation_nameEPKc', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEEl', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKvl', 'type': 'FUNC'} @@ -1221,6 +1222,7 @@ {'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD2Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__123__atomic_monitor_globalEPKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEE', 'type': 'FUNC'} @@ -1228,9 +1230,14 @@ {'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_all_nativeILm8EEEvPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_one_nativeILm8EEEvPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__126__atomic_wait_global_tableEPKvl', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__13cinE', 'size': 400, 'type': 'OBJECT'} diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist index 9016607..5732ed7 100644 --- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist +++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist @@ -225,6 +225,7 @@ {'is_defined': True, 'name': '_ZNKSt3__115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt3__115error_condition7messageEv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'} @@ -773,6 +774,7 @@ {'is_defined': True, 'name': '_ZNSt3__112system_errorD0Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__112system_errorD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__112system_errorD2Ev', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'} @@ -953,7 +955,6 @@ {'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'} -{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'} @@ -1156,7 +1157,6 @@ {'is_defined': True, 'name': '_ZNSt3__117bad_function_callD0Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117bad_function_callD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117bad_function_callD2Ev', 'type': 'FUNC'} -{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117iostream_categoryEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'} @@ -1206,6 +1206,7 @@ {'is_defined': True, 'name': '_ZNSt3__119__thread_local_dataEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__120__atomic_wait_nativeILm4EEEvPKvS2_', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__120__get_collation_nameEPKc', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEEi', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKvi', 'type': 'FUNC'} @@ -1219,6 +1220,7 @@ {'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD2Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__123__atomic_monitor_globalEPKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'} @@ -1226,9 +1228,14 @@ {'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_all_nativeILm4EEEvPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_one_nativeILm4EEEvPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__126__atomic_wait_global_tableEPKvi', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__13cinE', 'size': 280, 'type': 'OBJECT'} diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist index 5855c17..c7183c2 100644 --- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist +++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist @@ -196,6 +196,7 @@ {'is_defined': True, 'name': '_ZNKSt3__115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt3__115error_condition7messageEv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'} @@ -744,6 +745,7 @@ {'is_defined': True, 'name': '_ZNSt3__112system_errorD0Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__112system_errorD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__112system_errorD2Ev', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'} @@ -923,7 +925,6 @@ {'is_defined': True, 'name': '_ZNSt3__113random_deviceclEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'} -{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'} @@ -1127,7 +1128,6 @@ {'is_defined': True, 'name': '_ZNSt3__117bad_function_callD0Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117bad_function_callD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117bad_function_callD2Ev', 'type': 'FUNC'} -{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117iostream_categoryEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'} @@ -1177,6 +1177,7 @@ {'is_defined': True, 'name': '_ZNSt3__119__thread_local_dataEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__120__atomic_wait_nativeILm4EEEvPKvS2_', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__120__get_collation_nameEPKc', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEEi', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKvi', 'type': 'FUNC'} @@ -1190,6 +1191,7 @@ {'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD2Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__123__atomic_monitor_globalEPKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'} @@ -1197,9 +1199,14 @@ {'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_all_nativeILm4EEEvPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__126__atomic_notify_one_nativeILm4EEEvPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__126__atomic_wait_global_tableEPKvi', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_all_global_tableEPKv', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__132__atomic_notify_one_global_tableEPKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__13cinE', 'size': 280, 'type': 'OBJECT'} diff --git a/libcxx/modules/std/optional.inc b/libcxx/modules/std/optional.inc index 9ee5111..88de0bb 100644 --- a/libcxx/modules/std/optional.inc +++ b/libcxx/modules/std/optional.inc @@ -13,8 +13,9 @@ export namespace std { #if _LIBCPP_STD_VER >= 26 // [optional.iterators], iterator support namespace ranges { + using std::ranges::enable_borrowed_range; using std::ranges::enable_view; - } + } // namespace ranges #endif // [optional.nullopt], no-value state indicator using std::nullopt; diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp index b214ba1..2b1ebfa 100644 --- a/libcxx/src/atomic.cpp +++ b/libcxx/src/atomic.cpp @@ -9,8 +9,12 @@ #include <__thread/timed_backoff_policy.h> #include <atomic> #include <climits> +#include <cstddef> +#include <cstring> #include <functional> +#include <new> #include <thread> +#include <type_traits> #include "include/apple_availability.h" @@ -41,6 +45,11 @@ // OpenBSD has no indirect syscalls # define _LIBCPP_FUTEX(...) futex(__VA_ARGS__) +#elif defined(_WIN32) + +# include <memory> +# include <windows.h> + #else // <- Add other operating systems here // Baseline needs no new headers @@ -53,13 +62,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD #ifdef __linux__ -static void -__libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr, __cxx_contention_t __val) { +template <std::size_t _Size> +static void __platform_wait_on_address(void const* __ptr, void const* __val) { + static_assert(_Size == 4, "Can only wait on 4 bytes value"); + char buffer[_Size]; + std::memcpy(&buffer, const_cast<const void*>(__val), _Size); static constexpr timespec __timeout = {2, 0}; - _LIBCPP_FUTEX(__ptr, FUTEX_WAIT_PRIVATE, __val, &__timeout, 0, 0); + _LIBCPP_FUTEX(__ptr, FUTEX_WAIT_PRIVATE, *reinterpret_cast<__cxx_contention_t const*>(&buffer), &__timeout, 0, 0); } -static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr, bool __notify_one) { +template <std::size_t _Size> +static void __platform_wake_by_address(void const* __ptr, bool __notify_one) { + static_assert(_Size == 4, "Can only wake up on 4 bytes value"); _LIBCPP_FUTEX(__ptr, FUTEX_WAKE_PRIVATE, __notify_one ? 1 : INT_MAX, 0, 0, 0); } @@ -70,19 +84,29 @@ extern "C" int __ulock_wait( extern "C" int __ulock_wake(uint32_t operation, void* addr, uint64_t wake_value); // https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/sys/ulock.h#L82 +# define UL_COMPARE_AND_WAIT 1 # define UL_COMPARE_AND_WAIT64 5 # define ULF_WAKE_ALL 0x00000100 -static void -__libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr, __cxx_contention_t __val) { - static_assert(sizeof(__cxx_atomic_contention_t) == 8, "Waiting on 8 bytes value"); - __ulock_wait(UL_COMPARE_AND_WAIT64, const_cast<__cxx_atomic_contention_t*>(__ptr), __val, 0); +template <std::size_t _Size> +static void __platform_wait_on_address(void const* __ptr, void const* __val) { + static_assert(_Size == 8 || _Size == 4, "Can only wait on 8 bytes or 4 bytes value"); + char buffer[_Size]; + std::memcpy(&buffer, const_cast<const void*>(__val), _Size); + if constexpr (_Size == 4) + __ulock_wait(UL_COMPARE_AND_WAIT, const_cast<void*>(__ptr), *reinterpret_cast<uint32_t const*>(&buffer), 0); + else + __ulock_wait(UL_COMPARE_AND_WAIT64, const_cast<void*>(__ptr), *reinterpret_cast<uint64_t const*>(&buffer), 0); } -static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr, bool __notify_one) { - static_assert(sizeof(__cxx_atomic_contention_t) == 8, "Waking up on 8 bytes value"); - __ulock_wake( - UL_COMPARE_AND_WAIT64 | (__notify_one ? 0 : ULF_WAKE_ALL), const_cast<__cxx_atomic_contention_t*>(__ptr), 0); +template <std::size_t _Size> +static void __platform_wake_by_address(void const* __ptr, bool __notify_one) { + static_assert(_Size == 8 || _Size == 4, "Can only wake up on 8 bytes or 4 bytes value"); + + if constexpr (_Size == 4) + __ulock_wake(UL_COMPARE_AND_WAIT | (__notify_one ? 0 : ULF_WAKE_ALL), const_cast<void*>(__ptr), 0); + else + __ulock_wake(UL_COMPARE_AND_WAIT64 | (__notify_one ? 0 : ULF_WAKE_ALL), const_cast<void*>(__ptr), 0); } #elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8 @@ -92,119 +116,298 @@ static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const vo * limit its use to architectures where long and int64_t are synonyms. */ -static void -__libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr, __cxx_contention_t __val) { - _umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr), UMTX_OP_WAIT, __val, nullptr, nullptr); +template <std::size_t _Size> +static void __platform_wait_on_address(void const* __ptr, void const* __val) { + static_assert(_Size == 8, "Can only wait on 8 bytes value"); + char buffer[_Size]; + std::memcpy(&buffer, const_cast<const void*>(__val), _Size); + _umtx_op(const_cast<void*>(__ptr), UMTX_OP_WAIT, *reinterpret_cast<__cxx_contention_t*>(&buffer), nullptr, nullptr); } -static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr, bool __notify_one) { - _umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr), UMTX_OP_WAKE, __notify_one ? 1 : INT_MAX, nullptr, nullptr); +template <std::size_t _Size> +static void __platform_wake_by_address(void const* __ptr, bool __notify_one) { + static_assert(_Size == 8, "Can only wake up on 8 bytes value"); + _umtx_op(const_cast<void*>(__ptr), UMTX_OP_WAKE, __notify_one ? 1 : INT_MAX, nullptr, nullptr); +} + +#elif defined(_WIN32) + +static void* win32_get_synch_api_function(const char* function_name) { + // Attempt to load the API set. Note that as per the Microsoft STL implementation, we assume this API is already + // loaded and accessible. While this isn't explicitly guaranteed by publicly available Win32 API documentation, it is + // true in practice, and may be guaranteed by internal documentation not released publicly. In any case the fact that + // the Microsoft STL made this assumption is reasonable basis to say that we can too. The alternative to this would be + // to use LoadLibrary, but then leak the module handle. We can't call FreeLibrary, as this would have to be triggered + // by a global static destructor, which would hang off DllMain, and calling FreeLibrary from DllMain is explicitly + // mentioned as not being allowed: + // https://learn.microsoft.com/en-us/windows/win32/dlls/dllmain + // Given the range of bad options here, we have chosen to mirror what Microsoft did, as it seems fair to assume that + // Microsoft will guarantee compatibility for us, as we are exposed to the same conditions as all existing Windows + // apps using the Microsoft STL VS2015/2017/2019/2022 runtimes, where Windows 7 support has not been excluded at + // compile time. + static auto module_handle = GetModuleHandleW(L"api-ms-win-core-synch-l1-2-0.dll"); + if (module_handle == nullptr) { + return nullptr; + } + + // Attempt to locate the function in the API and return the result to the caller. Note that the NULL return from this + // method is documented as being interchangeable with nullptr. + // https://devblogs.microsoft.com/oldnewthing/20180307-00/?p=98175 + return reinterpret_cast<void*>(GetProcAddress(module_handle, function_name)); +} + +template <std::size_t _Size> +static void __platform_wait_on_address(void const* __ptr, void const* __val) { + static_assert(_Size == 8, "Can only wait on 8 bytes value"); + // WaitOnAddress was added in Windows 8 (build 9200) + static auto wait_on_address = + reinterpret_cast<BOOL(WINAPI*)(void*, PVOID, SIZE_T, DWORD)>(win32_get_synch_api_function("WaitOnAddress")); + if (wait_on_address != nullptr) { + wait_on_address(const_cast<void*>(__ptr), const_cast<void*>(__val), _Size, INFINITE); + } else { + __libcpp_thread_poll_with_backoff( + [=]() -> bool { return std::memcmp(const_cast<const void*>(__ptr), __val, _Size) != 0; }, + __libcpp_timed_backoff_policy()); + } +} + +template <std::size_t _Size> +static void __platform_wake_by_address(void const* __ptr, bool __notify_one) { + static_assert(_Size == 8, "Can only wake up on 8 bytes value"); + if (__notify_one) { + // WakeByAddressSingle was added in Windows 8 (build 9200) + static auto wake_by_address_single = + reinterpret_cast<void(WINAPI*)(PVOID)>(win32_get_synch_api_function("WakeByAddressSingle")); + if (wake_by_address_single != nullptr) { + wake_by_address_single(const_cast<void*>(__ptr)); + } else { + // The fallback implementation of waking does nothing, as the fallback wait implementation just does polling, so + // there's nothing to do here. + } + } else { + // WakeByAddressAll was added in Windows 8 (build 9200) + static auto wake_by_address_all = + reinterpret_cast<void(WINAPI*)(PVOID)>(win32_get_synch_api_function("WakeByAddressAll")); + if (wake_by_address_all != nullptr) { + wake_by_address_all(const_cast<void*>(__ptr)); + } else { + // The fallback implementation of waking does nothing, as the fallback wait implementation just does polling, so + // there's nothing to do here. + } + } } #else // <- Add other operating systems here // Baseline is just a timed backoff -static void -__libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr, __cxx_contention_t __val) { +template <std::size_t _Size> +static void __platform_wait_on_address(void const* __ptr, void const* __val) { __libcpp_thread_poll_with_backoff( - [=]() -> bool { return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__ptr, memory_order_relaxed), __val); }, + [=]() -> bool { return std::memcmp(const_cast<const void*>(__ptr), __val, _Size) != 0; }, __libcpp_timed_backoff_policy()); } -static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile*, bool) {} +template <std::size_t _Size> +static void __platform_wake_by_address(void const*, bool) {} #endif // __linux__ -static constexpr size_t __libcpp_contention_table_size = (1 << 8); /* < there's no magic in this number */ - -struct alignas(64) /* aim to avoid false sharing */ __libcpp_contention_table_entry { - __cxx_atomic_contention_t __contention_state; - __cxx_atomic_contention_t __platform_state; - inline constexpr __libcpp_contention_table_entry() : __contention_state(0), __platform_state(0) {} -}; - -static __libcpp_contention_table_entry __libcpp_contention_table[__libcpp_contention_table_size]; - -static hash<void const volatile*> __libcpp_contention_hasher; - -static __libcpp_contention_table_entry* __libcpp_contention_state(void const volatile* p) { - return &__libcpp_contention_table[__libcpp_contention_hasher(p) & (__libcpp_contention_table_size - 1)]; -} +// ============================= +// Local hidden helper functions +// ============================= /* Given an atomic to track contention and an atomic to actually wait on, which may be the same atomic, we try to detect contention to avoid spuriously calling the platform. */ -static void __libcpp_contention_notify(__cxx_atomic_contention_t volatile* __contention_state, - __cxx_atomic_contention_t const volatile* __platform_state, - bool __notify_one) { - if (0 != __cxx_atomic_load(__contention_state, memory_order_seq_cst)) +template <std::size_t _Size> +static void +__contention_notify(__cxx_atomic_contention_t* __waiter_count, void const* __address_to_notify, bool __notify_one) { + if (0 != __cxx_atomic_load(__waiter_count, memory_order_seq_cst)) // We only call 'wake' if we consumed a contention bit here. - __libcpp_platform_wake_by_address(__platform_state, __notify_one); -} -static __cxx_contention_t -__libcpp_contention_monitor_for_wait(__cxx_atomic_contention_t volatile* /*__contention_state*/, - __cxx_atomic_contention_t const volatile* __platform_state) { - // We will monitor this value. - return __cxx_atomic_load(__platform_state, memory_order_acquire); -} -static void __libcpp_contention_wait(__cxx_atomic_contention_t volatile* __contention_state, - __cxx_atomic_contention_t const volatile* __platform_state, - __cxx_contention_t __old_value) { - __cxx_atomic_fetch_add(__contention_state, __cxx_contention_t(1), memory_order_relaxed); + __platform_wake_by_address<_Size>(__address_to_notify, __notify_one); +} + +template <std::size_t _Size> +static void +__contention_wait(__cxx_atomic_contention_t* __waiter_count, void const* __address_to_wait, void const* __old_value) { + __cxx_atomic_fetch_add(__waiter_count, __cxx_contention_t(1), memory_order_relaxed); // https://llvm.org/PR109290 // There are no platform guarantees of a memory barrier in the platform wait implementation __cxx_atomic_thread_fence(memory_order_seq_cst); // We sleep as long as the monitored value hasn't changed. - __libcpp_platform_wait_on_address(__platform_state, __old_value); - __cxx_atomic_fetch_sub(__contention_state, __cxx_contention_t(1), memory_order_release); + __platform_wait_on_address<_Size>(__address_to_wait, __old_value); + __cxx_atomic_fetch_sub(__waiter_count, __cxx_contention_t(1), memory_order_release); +} + +#if defined(__APPLE__) && defined(__aarch64__) +static constexpr size_t __cache_line_size = 128; +#elif defined(__cpp_lib_hardware_interference_size) +static constexpr size_t __cache_line_size = std::hardware_constructive_interference_size; +#else +static constexpr size_t __cache_line_size = 64; +#endif + +static constexpr size_t __contention_table_size = (1 << 8); /* < there's no magic in this number */ + +static constexpr hash<void const*> __contention_hasher; + +// Waiter count table for all atomics with the correct size that use itself as the wait/notify address. + +struct alignas(__cache_line_size) /* aim to avoid false sharing */ __contention_state_native { + __cxx_atomic_contention_t __waiter_count; + constexpr __contention_state_native() : __waiter_count(0) {} +}; + +static __contention_state_native __contention_table_native[__contention_table_size]; + +static __cxx_atomic_contention_t* __get_native_waiter_count(void const* p) { + return &__contention_table_native[__contention_hasher(p) & (__contention_table_size - 1)].__waiter_count; +} + +// Global contention table for all atomics with the wrong size that use the global table's atomic as wait/notify +// address. + +struct alignas(__cache_line_size) /* aim to avoid false sharing */ __contention_state_global { + __cxx_atomic_contention_t __waiter_count; + __cxx_atomic_contention_t __platform_state; + constexpr __contention_state_global() : __waiter_count(0), __platform_state(0) {} +}; + +static __contention_state_global __contention_table_global[__contention_table_size]; + +static __contention_state_global* __get_global_contention_state(void const* p) { + return &__contention_table_global[__contention_hasher(p) & (__contention_table_size - 1)]; } /* When the incoming atomic is the wrong size for the platform wait size, need to launder the value sequence through an atomic from our table. */ -static void __libcpp_atomic_notify(void const volatile* __location) { - auto const __entry = __libcpp_contention_state(__location); +static void __atomic_notify_global_table(void const* __location) { + auto const __entry = __get_global_contention_state(__location); // The value sequence laundering happens on the next line below. __cxx_atomic_fetch_add(&__entry->__platform_state, __cxx_contention_t(1), memory_order_seq_cst); - __libcpp_contention_notify( - &__entry->__contention_state, - &__entry->__platform_state, - false /* when laundering, we can't handle notify_one */); + __contention_notify<sizeof(__cxx_atomic_contention_t)>( + &__entry->__waiter_count, &__entry->__platform_state, false /* when laundering, we can't handle notify_one */); } + +// ============================= +// New dylib exported symbols +// ============================= + +// global +_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __atomic_monitor_global(void const* __location) noexcept { + auto const __entry = __get_global_contention_state(__location); + return __cxx_atomic_load(&__entry->__platform_state, memory_order_acquire); +} + +_LIBCPP_EXPORTED_FROM_ABI void +__atomic_wait_global_table(void const* __location, __cxx_contention_t __old_value) noexcept { + auto const __entry = __get_global_contention_state(__location); + __contention_wait<sizeof(__cxx_atomic_contention_t)>( + &__entry->__waiter_count, &__entry->__platform_state, &__old_value); +} + +_LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_global_table(void const* __location) noexcept { + __atomic_notify_global_table(__location); +} + +_LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_global_table(void const* __location) noexcept { + __atomic_notify_global_table(__location); +} + +// native + +template <std::size_t _Size> +_LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_native(void const* __address, void const* __old_value) noexcept { + __contention_wait<_Size>(__get_native_waiter_count(__address), __address, __old_value); +} + +template <std::size_t _Size> +_LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_native(void const* __location) noexcept { + __contention_notify<_Size>(__get_native_waiter_count(__location), __location, true); +} + +template <std::size_t _Size> +_LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_native(void const* __location) noexcept { + __contention_notify<_Size>(__get_native_waiter_count(__location), __location, false); +} + +// ================================================== +// Instantiation of the templates with supported size +// ================================================== + +#if defined(_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE) + +# define _INSTANTIATE(_SIZE) \ + template _LIBCPP_EXPORTED_FROM_ABI void __atomic_wait_native<_SIZE>(void const*, void const*) noexcept; \ + template _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_one_native<_SIZE>(void const*) noexcept; \ + template _LIBCPP_EXPORTED_FROM_ABI void __atomic_notify_all_native<_SIZE>(void const*) noexcept; + +_LIBCPP_NATIVE_PLATFORM_WAIT_SIZES(_INSTANTIATE) + +# undef _INSTANTIATE + +#else // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE + +template _LIBCPP_EXPORTED_FROM_ABI void +__atomic_wait_native<sizeof(__cxx_contention_t)>(void const* __address, void const* __old_value) noexcept; + +template _LIBCPP_EXPORTED_FROM_ABI void +__atomic_notify_one_native<sizeof(__cxx_contention_t)>(void const* __location) noexcept; + +template _LIBCPP_EXPORTED_FROM_ABI void +__atomic_notify_all_native<sizeof(__cxx_contention_t)>(void const* __location) noexcept; + +#endif // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE + +// ============================================================= +// Old dylib exported symbols, for backwards compatibility +// ============================================================= + _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile* __location) noexcept { - __libcpp_atomic_notify(__location); + __atomic_notify_global_table(const_cast<void const*>(__location)); } + _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile* __location) noexcept { - __libcpp_atomic_notify(__location); + __atomic_notify_global_table(const_cast<void const*>(__location)); } + _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile* __location) noexcept { - auto const __entry = __libcpp_contention_state(__location); - return __libcpp_contention_monitor_for_wait(&__entry->__contention_state, &__entry->__platform_state); + auto const __entry = __get_global_contention_state(const_cast<void const*>(__location)); + return __cxx_atomic_load(&__entry->__platform_state, memory_order_acquire); } + _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile* __location, __cxx_contention_t __old_value) noexcept { - auto const __entry = __libcpp_contention_state(__location); - __libcpp_contention_wait(&__entry->__contention_state, &__entry->__platform_state, __old_value); + auto const __entry = __get_global_contention_state(const_cast<void const*>(__location)); + __contention_wait<sizeof(__cxx_atomic_contention_t)>( + &__entry->__waiter_count, &__entry->__platform_state, &__old_value); } -/* When the incoming atomic happens to be the platform wait size, we still need to use the - table for the contention detection, but we can use the atomic directly for the wait. */ - _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile* __location) noexcept { - __libcpp_contention_notify(&__libcpp_contention_state(__location)->__contention_state, __location, true); + auto __location_cast = const_cast<const void*>(static_cast<const volatile void*>(__location)); + __contention_notify<sizeof(__cxx_atomic_contention_t)>( + __get_native_waiter_count(__location_cast), __location_cast, true); } + _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile* __location) noexcept { - __libcpp_contention_notify(&__libcpp_contention_state(__location)->__contention_state, __location, false); -} -// This function is never used, but still exported for ABI compatibility. -_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t -__libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile* __location) noexcept { - return __libcpp_contention_monitor_for_wait(&__libcpp_contention_state(__location)->__contention_state, __location); + auto __location_cast = const_cast<const void*>(static_cast<const volatile void*>(__location)); + __contention_notify<sizeof(__cxx_atomic_contention_t)>( + __get_native_waiter_count(__location_cast), __location_cast, false); } + _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile* __location, __cxx_contention_t __old_value) noexcept { - __libcpp_contention_wait(&__libcpp_contention_state(__location)->__contention_state, __location, __old_value); + auto __location_cast = const_cast<const void*>(static_cast<const volatile void*>(__location)); + __contention_wait<sizeof(__cxx_atomic_contention_t)>( + __get_native_waiter_count(__location_cast), __location_cast, &__old_value); +} + +// this function is even unused in the old ABI +_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t +__libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile* __location) noexcept { + return __cxx_atomic_load(__location, memory_order_acquire); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/src/exception.cpp b/libcxx/src/exception.cpp index ac6324c..9932141 100644 --- a/libcxx/src/exception.cpp +++ b/libcxx/src/exception.cpp @@ -9,20 +9,12 @@ #define _LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION #define _LIBCPP_DISABLE_DEPRECATION_WARNINGS -#include <exception> -#include <new> -#include <typeinfo> - -#if defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI) -# include <cxxabi.h> -using namespace __cxxabiv1; -# define HAVE_DEPENDENT_EH_ABI 1 -#endif +#include <__config> #if defined(_LIBCPP_ABI_MICROSOFT) # include "support/runtime/exception_msvc.ipp" # include "support/runtime/exception_pointer_msvc.ipp" -#elif defined(_LIBCPPABI_VERSION) +#elif defined(LIBCXX_BUILDING_LIBCXXABI) # include "support/runtime/exception_libcxxabi.ipp" # include "support/runtime/exception_pointer_cxxabi.ipp" #elif defined(LIBCXXRT) diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp index b71f94a..745db87 100644 --- a/libcxx/src/filesystem/operations.cpp +++ b/libcxx/src/filesystem/operations.cpp @@ -41,17 +41,10 @@ #include <time.h> // since Linux 4.5 and FreeBSD 13, but the Linux libc wrapper is only provided by glibc >= 2.27 and musl -#if defined(__linux__) -# if defined(_LIBCPP_GLIBC_PREREQ) -# if _LIBCPP_GLIBC_PREREQ(2, 27) -# define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE -# endif -# elif _LIBCPP_HAS_MUSL_LIBC -# define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE -# endif -#elif defined(__FreeBSD__) +#if _LIBCPP_GLIBC_PREREQ(2, 27) || _LIBCPP_HAS_MUSL_LIBC || defined(__FreeBSD__) # define _LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE #endif + #if __has_include(<sys/sendfile.h>) # include <sys/sendfile.h> # define _LIBCPP_FILESYSTEM_USE_SENDFILE diff --git a/libcxx/include/__memory/aligned_alloc.h b/libcxx/src/include/aligned_alloc.h index fb36983..24ca26c 100644 --- a/libcxx/include/__memory/aligned_alloc.h +++ b/libcxx/src/include/aligned_alloc.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_ALIGNED_ALLOC_H -#define _LIBCPP___MEMORY_ALIGNED_ALLOC_H +#ifndef _LIBCPP_SRC_ALIGNED_ALLOC_H +#define _LIBCPP_SRC_ALIGNED_ALLOC_H #include <__config> #include <cstdlib> @@ -29,7 +29,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD inline _LIBCPP_HIDE_FROM_ABI void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) { # if defined(_LIBCPP_MSVCRT_LIKE) return ::_aligned_malloc(__size, __alignment); -# elif _LIBCPP_STD_VER >= 17 && _LIBCPP_HAS_C11_ALIGNED_ALLOC + +// Android only provides aligned_alloc when targeting API 28 or higher. +# elif !defined(__ANDROID__) || __ANDROID_API__ >= 28 // aligned_alloc() requires that __size is a multiple of __alignment, // but for C++ [new.delete.general], only states "if the value of an // alignment argument passed to any of these functions is not a valid @@ -60,4 +62,4 @@ inline _LIBCPP_HIDE_FROM_ABI void __libcpp_aligned_free(void* __ptr) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MEMORY_ALIGNED_ALLOC_H +#endif // _LIBCPP_SRC_ALIGNED_ALLOC_H diff --git a/libcxx/src/include/config_elast.h b/libcxx/src/include/config_elast.h index 7edff2d..be665a9 100644 --- a/libcxx/src/include/config_elast.h +++ b/libcxx/src/include/config_elast.h @@ -23,7 +23,7 @@ # define _LIBCPP_ELAST ELAST #elif defined(__LLVM_LIBC__) // No _LIBCPP_ELAST needed for LLVM libc -#elif defined(_NEWLIB_VERSION) +#elif _LIBCPP_LIBC_NEWLIB # define _LIBCPP_ELAST __ELASTERROR #elif defined(__NuttX__) // No _LIBCPP_ELAST needed on NuttX diff --git a/libcxx/src/include/from_chars_floating_point.h b/libcxx/src/include/from_chars_floating_point.h index 19eeeb2..20f23d2 100644 --- a/libcxx/src/include/from_chars_floating_point.h +++ b/libcxx/src/include/from_chars_floating_point.h @@ -9,11 +9,6 @@ #ifndef _LIBCPP_SRC_INCLUDE_FROM_CHARS_FLOATING_POINT_H #define _LIBCPP_SRC_INCLUDE_FROM_CHARS_FLOATING_POINT_H -// These headers are in the shared LLVM-libc header library. -#include "shared/fp_bits.h" -#include "shared/str_to_float.h" -#include "shared/str_to_integer.h" - #include <__assert> #include <__config> #include <cctype> @@ -21,6 +16,15 @@ #include <concepts> #include <limits> +// Make sure we use libc++'s assertion machinery within the shared code we use +// from LLVM libc. +#define LIBC_ASSERT(cond) _LIBCPP_ASSERT((cond), _LIBCPP_TOSTRING(cond)) + +// These headers are in the shared LLVM-libc header library. +#include "shared/fp_bits.h" +#include "shared/str_to_float.h" +#include "shared/str_to_integer.h" + // Included for the _Floating_type_traits class #include "to_chars_floating_point.h" diff --git a/libcxx/src/include/refstring.h b/libcxx/src/include/refstring.h index 3e0ec7a..1c73c60 100644 --- a/libcxx/src/include/refstring.h +++ b/libcxx/src/include/refstring.h @@ -15,7 +15,7 @@ #include <cstring> #include <stdexcept> -// MacOS and iOS used to ship with libstdc++, and still support old applications +// MacOS used to ship with libstdc++, and still support old applications // linking against libstdc++. The libc++ and libstdc++ exceptions are supposed // to be ABI compatible, such that they can be thrown from one library and caught // in the other. @@ -25,7 +25,7 @@ // string singleton before manipulating the reference count. This is done so that // if an exception is created with a zero-length string in libstdc++, libc++abi // won't try to delete the memory. -#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) # define _LIBCPP_CHECK_FOR_GCC_EMPTY_STRING_STORAGE # include <dlfcn.h> # include <mach-o/dyld.h> diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp index 0f695d4..aca2117 100644 --- a/libcxx/src/locale.cpp +++ b/libcxx/src/locale.cpp @@ -919,7 +919,7 @@ const ctype<char>::mask* ctype<char>::classic_table() noexcept { return __pctype_func(); # elif defined(__EMSCRIPTEN__) return *__ctype_b_loc(); -# elif defined(_NEWLIB_VERSION) +# elif _LIBCPP_LIBC_NEWLIB // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1]. return _ctype_ + 1; # elif defined(_AIX) @@ -5557,6 +5557,54 @@ string __num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _C return __np.grouping(); } +template <class _CharT> +int __num_get<_CharT>::__stage2_int_loop( + _CharT __ct, + int __base, + char* __a, + char*& __a_end, + unsigned& __dc, + _CharT __thousands_sep, + const string& __grouping, + unsigned* __g, + unsigned*& __g_end, + _CharT* __atoms) { + if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25])) { + *__a_end++ = __ct == __atoms[24] ? '+' : '-'; + __dc = 0; + return 0; + } + if (__grouping.size() != 0 && __ct == __thousands_sep) { + if (__g_end - __g < __num_get_buf_sz) { + *__g_end++ = __dc; + __dc = 0; + } + return 0; + } + ptrdiff_t __f = __atoms_offset(__atoms, __ct); + if (__f >= 24) + return -1; + switch (__base) { + case 8: + case 10: + if (__f >= __base) + return -1; + break; + case 16: + if (__f < 22) + break; + if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0') { + __dc = 0; + *__a_end++ = __src[__f]; + return 0; + } + return -1; + } + *__a_end++ = __src[__f]; + ++__dc; + return 0; +} + template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<char>; _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<wchar_t>;) diff --git a/libcxx/src/new.cpp b/libcxx/src/new.cpp index ce6b637..70cdab6 100644 --- a/libcxx/src/new.cpp +++ b/libcxx/src/new.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// +#include "include/aligned_alloc.h" #include "include/overridable_function.h" #include <__assert> -#include <__memory/aligned_alloc.h> #include <cstddef> #include <cstdlib> #include <new> diff --git a/libcxx/src/print.cpp b/libcxx/src/print.cpp index 3f2baa6..82cf2af 100644 --- a/libcxx/src/print.cpp +++ b/libcxx/src/print.cpp @@ -22,6 +22,14 @@ # include <windows.h> #elif __has_include(<unistd.h>) # include <unistd.h> +# if defined(_NEWLIB_VERSION) +# if defined(_POSIX_C_SOURCE) && __has_include(<stdio.h>) +# include <stdio.h> +# define HAS_FILENO_AND_ISATTY +# endif +# else +# define HAS_FILENO_AND_ISATTY +# endif #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -56,7 +64,7 @@ __write_to_windows_console([[maybe_unused]] FILE* __stream, [[maybe_unused]] wst } # endif // _LIBCPP_HAS_WIDE_CHARACTERS -#elif __has_include(<unistd.h>) // !_LIBCPP_WIN32API +#elif defined(HAS_FILENO_AND_ISATTY) // !_LIBCPP_WIN32API _LIBCPP_EXPORTED_FROM_ABI bool __is_posix_terminal(FILE* __stream) { return isatty(fileno(__stream)); } #endif diff --git a/libcxx/src/support/runtime/exception_fallback.ipp b/libcxx/src/support/runtime/exception_fallback.ipp index ba283ae..dca904e 100644 --- a/libcxx/src/support/runtime/exception_fallback.ipp +++ b/libcxx/src/support/runtime/exception_fallback.ipp @@ -8,6 +8,8 @@ //===----------------------------------------------------------------------===// #include <__verbose_abort> +#include <exception> +#include "include/atomic_support.h" namespace std { diff --git a/libcxx/src/support/runtime/exception_glibcxx.ipp b/libcxx/src/support/runtime/exception_glibcxx.ipp index aa67cab..5eb8d87 100644 --- a/libcxx/src/support/runtime/exception_glibcxx.ipp +++ b/libcxx/src/support/runtime/exception_glibcxx.ipp @@ -11,6 +11,9 @@ # error header can only be used when targeting libstdc++ or libsupc++ #endif +#include <exception> +#include <new> + namespace std { bad_alloc::bad_alloc() noexcept {} diff --git a/libcxx/src/support/runtime/exception_libcxxabi.ipp b/libcxx/src/support/runtime/exception_libcxxabi.ipp index df6bd65..c42bb23 100644 --- a/libcxx/src/support/runtime/exception_libcxxabi.ipp +++ b/libcxx/src/support/runtime/exception_libcxxabi.ipp @@ -7,6 +7,10 @@ // //===----------------------------------------------------------------------===// +#include <exception> + +#include <cxxabi.h> + #ifndef _LIBCPPABI_VERSION # error this header can only be used with libc++abi #endif @@ -17,9 +21,9 @@ bool uncaught_exception() noexcept { return uncaught_exceptions() > 0; } int uncaught_exceptions() noexcept { #if _LIBCPPABI_VERSION > 1001 - return __cxa_uncaught_exceptions(); + return abi::__cxa_uncaught_exceptions(); #else - return __cxa_uncaught_exception() ? 1 : 0; + return abi::__cxa_uncaught_exception() ? 1 : 0; #endif } diff --git a/libcxx/src/support/runtime/exception_libcxxrt.ipp b/libcxx/src/support/runtime/exception_libcxxrt.ipp index f17fecc..6afdc00 100644 --- a/libcxx/src/support/runtime/exception_libcxxrt.ipp +++ b/libcxx/src/support/runtime/exception_libcxxrt.ipp @@ -11,6 +11,8 @@ # error this header may only be used when targeting libcxxrt #endif +#include <exception> + namespace std { bad_exception::~bad_exception() noexcept {} diff --git a/libcxx/src/support/runtime/exception_msvc.ipp b/libcxx/src/support/runtime/exception_msvc.ipp index 2ae004b..7114d90 100644 --- a/libcxx/src/support/runtime/exception_msvc.ipp +++ b/libcxx/src/support/runtime/exception_msvc.ipp @@ -12,6 +12,8 @@ #endif #include <__verbose_abort> +#include <exception> +#include <new> extern "C" { typedef void(__cdecl* terminate_handler)(); diff --git a/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp b/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp index 8f5c206..75cb7c9 100644 --- a/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp +++ b/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp @@ -7,22 +7,21 @@ // //===----------------------------------------------------------------------===// -#ifndef HAVE_DEPENDENT_EH_ABI -# error this header may only be used with libc++abi or libcxxrt -#endif +#include <cxxabi.h> +#include <exception> namespace std { -exception_ptr::~exception_ptr() noexcept { __cxa_decrement_exception_refcount(__ptr_); } +exception_ptr::~exception_ptr() noexcept { abi::__cxa_decrement_exception_refcount(__ptr_); } exception_ptr::exception_ptr(const exception_ptr& other) noexcept : __ptr_(other.__ptr_) { - __cxa_increment_exception_refcount(__ptr_); + abi::__cxa_increment_exception_refcount(__ptr_); } exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept { if (__ptr_ != other.__ptr_) { - __cxa_increment_exception_refcount(other.__ptr_); - __cxa_decrement_exception_refcount(__ptr_); + abi::__cxa_increment_exception_refcount(other.__ptr_); + abi::__cxa_decrement_exception_refcount(__ptr_); __ptr_ = other.__ptr_; } return *this; @@ -31,7 +30,7 @@ exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept { exception_ptr exception_ptr::__from_native_exception_pointer(void* __e) noexcept { exception_ptr ptr; ptr.__ptr_ = __e; - __cxa_increment_exception_refcount(ptr.__ptr_); + abi::__cxa_increment_exception_refcount(ptr.__ptr_); return ptr; } @@ -51,12 +50,12 @@ exception_ptr current_exception() noexcept { // this whole function would be just: // return exception_ptr(__cxa_current_primary_exception()); exception_ptr ptr; - ptr.__ptr_ = __cxa_current_primary_exception(); + ptr.__ptr_ = abi::__cxa_current_primary_exception(); return ptr; } void rethrow_exception(exception_ptr p) { - __cxa_rethrow_primary_exception(p.__ptr_); + abi::__cxa_rethrow_primary_exception(p.__ptr_); // if p.__ptr_ is NULL, above returns so we terminate terminate(); } diff --git a/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp b/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp index 174b44c..4b08db6 100644 --- a/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp +++ b/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp @@ -16,6 +16,8 @@ // stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr) // function. +#include <exception> + namespace std { namespace __exception_ptr { diff --git a/libcxx/src/support/runtime/exception_pointer_msvc.ipp b/libcxx/src/support/runtime/exception_pointer_msvc.ipp index 2be5136..4141e03 100644 --- a/libcxx/src/support/runtime/exception_pointer_msvc.ipp +++ b/libcxx/src/support/runtime/exception_pointer_msvc.ipp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include <exception> #include <stdio.h> #include <stdlib.h> diff --git a/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp b/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp index 05a71ce..5e55f0f 100644 --- a/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp +++ b/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include <__verbose_abort> +#include <exception> namespace std { diff --git a/libcxx/src/thread.cpp b/libcxx/src/thread.cpp index 028d36e..e494574 100644 --- a/libcxx/src/thread.cpp +++ b/libcxx/src/thread.cpp @@ -74,9 +74,7 @@ unsigned thread::hardware_concurrency() noexcept { return 0; return static_cast<unsigned>(result); #elif defined(_LIBCPP_WIN32API) - SYSTEM_INFO info; - GetSystemInfo(&info); - return info.dwNumberOfProcessors; + return static_cast<unsigned>(GetActiveProcessorCount(ALL_PROCESSOR_GROUPS)); #else // defined(CTL_HW) && defined(HW_NCPU) // TODO: grovel through /proc or check cpuid on x86 and similar // instructions on other architectures. diff --git a/libcxx/test/benchmarks/algorithms/nonmodifying/find.bench.cpp b/libcxx/test/benchmarks/algorithms/nonmodifying/find.bench.cpp index afea31f..7780b5a 100644 --- a/libcxx/test/benchmarks/algorithms/nonmodifying/find.bench.cpp +++ b/libcxx/test/benchmarks/algorithms/nonmodifying/find.bench.cpp @@ -12,6 +12,7 @@ #include <cstddef> #include <deque> #include <list> +#include <ranges> #include <string> #include <vector> @@ -83,6 +84,20 @@ int main(int argc, char** argv) { bm.template operator()<std::list<int>>("rng::find_if_not(list<int>) (" + comment + ")", ranges_find_if_not); }; + auto register_nested_container_benchmarks = [&](auto bm, std::string comment) { + // ranges_find + bm.template operator()<std::vector<std::vector<char>>>( + "rng::find(join_view(vector<vector<char>>)) (" + comment + ")", ranges_find); + bm.template operator()<std::vector<std::vector<int>>>( + "rng::find(join_view(vector<vector<int>>)) (" + comment + ")", ranges_find); + bm.template operator()<std::list<std::vector<int>>>( + "rng::find(join_view(list<vector<int>>)) (" + comment + ")", ranges_find); + bm.template operator()<std::vector<std::list<int>>>( + "rng::find(join_view(vector<list<int>>)) (" + comment + ")", ranges_find); + bm.template operator()<std::deque<std::deque<int>>>( + "rng::find(join_view(deque<deque<int>>)) (" + comment + ")", ranges_find); + }; + // Benchmark {std,ranges}::{find,find_if,find_if_not}(normal container) where we // bail out after 25% of elements { @@ -142,6 +157,44 @@ int main(int argc, char** argv) { register_benchmarks(bm, "process all"); } + // Benchmark {std,ranges}::{find,find_if,find_if_not}(join(normal container)) where we process the whole sequence + { + auto bm = []<class Container>(std::string name, auto find) { + benchmark::RegisterBenchmark( + name, + [find](auto& st) { + std::size_t const size = st.range(0); + std::size_t const seg_size = 256; + std::size_t const segments = (size + seg_size - 1) / seg_size; + using C1 = typename Container::value_type; + using ValueType = typename C1::value_type; + ValueType x = Generate<ValueType>::random(); + ValueType y = random_different_from({x}); + Container c(segments); + auto n = size; + for (auto it = c.begin(); it != c.end(); it++) { + it->resize(std::min(seg_size, n), x); + n -= it->size(); + } + + auto view = c | std::views::join; + + for ([[maybe_unused]] auto _ : st) { + benchmark::DoNotOptimize(c); + benchmark::DoNotOptimize(y); + auto result = find(view.begin(), view.end(), y); + benchmark::DoNotOptimize(result); + } + }) + ->Arg(8) + ->Arg(50) // non power-of-two + ->Arg(1024) + ->Arg(8192) + ->Arg(1 << 15); + }; + register_nested_container_benchmarks(bm, "process all"); + } + // Benchmark {std,ranges}::{find,find_if,find_if_not}(vector<bool>) where we process the whole sequence { auto bm = [](std::string name, auto find) { diff --git a/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h b/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h index 22a6d0d..5dd55f2 100644 --- a/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h +++ b/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h @@ -11,6 +11,7 @@ #include <algorithm> #include <iterator> +#include <memory_resource> #include <random> #include <string> #include <ranges> @@ -33,6 +34,9 @@ struct adapt_operations { // using InsertionResult = ...; // static Container::iterator get_iterator(InsertionResult const&); + + // template <class Allocator> + // using rebind_alloc = ...; }; template <class Container> @@ -103,6 +107,61 @@ void associative_container_benchmarks(std::string container) { } }); + bench("ctor(const&, alloc)", [=](auto& st) { + const std::size_t size = st.range(0); + std::vector<Value> in = make_value_types(generate_unique_keys(size)); + Container src(in.begin(), in.end()); + ScratchSpace c[BatchSize]; + + while (st.KeepRunningBatch(BatchSize)) { + for (std::size_t i = 0; i != BatchSize; ++i) { + new (c + i) Container(src, std::allocator<typename Container::value_type>()); + benchmark::DoNotOptimize(c + i); + benchmark::ClobberMemory(); + } + + st.PauseTiming(); + for (std::size_t i = 0; i != BatchSize; ++i) { + reinterpret_cast<Container*>(c + i)->~Container(); + } + st.ResumeTiming(); + } + }); + + bench("ctor(&&, different allocs)", [=](auto& st) { + using PMRContainer = adapt_operations<Container>::template rebind_alloc< + std::pmr::polymorphic_allocator<typename Container::value_type>>; + + const std::size_t size = st.range(0); + std::vector<Value> in = make_value_types(generate_unique_keys(size)); + std::pmr::monotonic_buffer_resource rs(size * 64 * BatchSize); // 64 bytes should be enough per node + std::vector<PMRContainer> srcs; + srcs.reserve(BatchSize); + for (size_t i = 0; i != BatchSize; ++i) + srcs.emplace_back(&rs).insert(in.begin(), in.end()); + alignas(PMRContainer) char c[BatchSize * sizeof(PMRContainer)]; + + std::pmr::monotonic_buffer_resource rs2(size * 64 * BatchSize); // 64 bytes should be enough per node + while (st.KeepRunningBatch(BatchSize)) { + for (std::size_t i = 0; i != BatchSize; ++i) { + new (c + i * sizeof(PMRContainer)) PMRContainer(std::move(srcs[i]), &rs2); + benchmark::DoNotOptimize(c + i); + benchmark::ClobberMemory(); + } + + st.PauseTiming(); + for (std::size_t i = 0; i != BatchSize; ++i) { + reinterpret_cast<PMRContainer*>(c + i * sizeof(PMRContainer))->~PMRContainer(); + } + rs2.release(); + srcs.clear(); + for (size_t i = 0; i != BatchSize; ++i) + srcs.emplace_back(&rs).insert(in.begin(), in.end()); + + st.ResumeTiming(); + } + }); + bench("ctor(iterator, iterator) (unsorted sequence)", [=](auto& st) { const std::size_t size = st.range(0); std::mt19937 randomness; diff --git a/libcxx/test/benchmarks/containers/associative/flat_map.bench.cpp b/libcxx/test/benchmarks/containers/associative/flat_map.bench.cpp index f3b8655..407afb1 100644 --- a/libcxx/test/benchmarks/containers/associative/flat_map.bench.cpp +++ b/libcxx/test/benchmarks/containers/associative/flat_map.bench.cpp @@ -24,6 +24,14 @@ struct support::adapt_operations<std::flat_map<K, V>> { using InsertionResult = std::pair<typename std::flat_map<K, V>::iterator, bool>; static auto get_iterator(InsertionResult const& result) { return result.first; } + + template <class Allocator> + using rebind_alloc = + std::flat_map<K, + V, + std::less<K>, + std::vector<K, typename std::allocator_traits<Allocator>::template rebind_alloc<K>>, + std::vector<V, typename std::allocator_traits<Allocator>::template rebind_alloc<V>>>; }; int main(int argc, char** argv) { diff --git a/libcxx/test/benchmarks/containers/associative/flat_multimap.bench.cpp b/libcxx/test/benchmarks/containers/associative/flat_multimap.bench.cpp index 80eaa5490..4f70d26 100644 --- a/libcxx/test/benchmarks/containers/associative/flat_multimap.bench.cpp +++ b/libcxx/test/benchmarks/containers/associative/flat_multimap.bench.cpp @@ -23,6 +23,14 @@ struct support::adapt_operations<std::flat_multimap<K, V>> { using InsertionResult = typename std::flat_multimap<K, V>::iterator; static auto get_iterator(InsertionResult const& result) { return result; } + + template <class Allocator> + using rebind_alloc = + std::flat_multimap<K, + V, + std::less<K>, + std::vector<K, typename std::allocator_traits<Allocator>::template rebind_alloc<K>>, + std::vector<V, typename std::allocator_traits<Allocator>::template rebind_alloc<V>>>; }; int main(int argc, char** argv) { diff --git a/libcxx/test/benchmarks/containers/associative/map.bench.cpp b/libcxx/test/benchmarks/containers/associative/map.bench.cpp index 142229a..cc9ffd8 100644 --- a/libcxx/test/benchmarks/containers/associative/map.bench.cpp +++ b/libcxx/test/benchmarks/containers/associative/map.bench.cpp @@ -38,6 +38,9 @@ struct support::adapt_operations<std::map<K, V>> { using InsertionResult = std::pair<typename std::map<K, V>::iterator, bool>; static auto get_iterator(InsertionResult const& result) { return result.first; } + + template <class Allocator> + using rebind_alloc = std::map<K, V, std::less<K>, Allocator>; }; int main(int argc, char** argv) { diff --git a/libcxx/test/benchmarks/containers/associative/multimap.bench.cpp b/libcxx/test/benchmarks/containers/associative/multimap.bench.cpp index 15a0b57..8e3abf0 100644 --- a/libcxx/test/benchmarks/containers/associative/multimap.bench.cpp +++ b/libcxx/test/benchmarks/containers/associative/multimap.bench.cpp @@ -24,6 +24,9 @@ struct support::adapt_operations<std::multimap<K, V>> { using InsertionResult = typename std::multimap<K, V>::iterator; static auto get_iterator(InsertionResult const& result) { return result; } + + template <class Allocator> + using rebind_alloc = std::multimap<K, V, std::less<K>, Allocator>; }; int main(int argc, char** argv) { diff --git a/libcxx/test/benchmarks/containers/associative/multiset.bench.cpp b/libcxx/test/benchmarks/containers/associative/multiset.bench.cpp index c205e0a..7bafd0a 100644 --- a/libcxx/test/benchmarks/containers/associative/multiset.bench.cpp +++ b/libcxx/test/benchmarks/containers/associative/multiset.bench.cpp @@ -22,6 +22,9 @@ struct support::adapt_operations<std::multiset<K>> { using InsertionResult = typename std::multiset<K>::iterator; static auto get_iterator(InsertionResult const& result) { return result; } + + template <class Allocator> + using rebind_alloc = std::multiset<K, std::less<K>, Allocator>; }; int main(int argc, char** argv) { diff --git a/libcxx/test/benchmarks/containers/associative/set.bench.cpp b/libcxx/test/benchmarks/containers/associative/set.bench.cpp index 50ee142..e5a6cc5 100644 --- a/libcxx/test/benchmarks/containers/associative/set.bench.cpp +++ b/libcxx/test/benchmarks/containers/associative/set.bench.cpp @@ -23,6 +23,9 @@ struct support::adapt_operations<std::set<K>> { using InsertionResult = std::pair<typename std::set<K>::iterator, bool>; static auto get_iterator(InsertionResult const& result) { return result.first; } + + template <class Allocator> + using rebind_alloc = std::set<K, std::less<K>, Allocator>; }; int main(int argc, char** argv) { diff --git a/libcxx/test/benchmarks/containers/associative/unordered_map.bench.cpp b/libcxx/test/benchmarks/containers/associative/unordered_map.bench.cpp index d670c53..ddfc90c 100644 --- a/libcxx/test/benchmarks/containers/associative/unordered_map.bench.cpp +++ b/libcxx/test/benchmarks/containers/associative/unordered_map.bench.cpp @@ -37,6 +37,9 @@ struct support::adapt_operations<std::unordered_map<K, V>> { using InsertionResult = std::pair<typename std::unordered_map<K, V>::iterator, bool>; static auto get_iterator(InsertionResult const& result) { return result.first; } + + template <class Allocator> + using rebind_alloc = std::unordered_map<K, V, std::hash<K>, std::equal_to<K>, Allocator>; }; int main(int argc, char** argv) { diff --git a/libcxx/test/benchmarks/containers/associative/unordered_multimap.bench.cpp b/libcxx/test/benchmarks/containers/associative/unordered_multimap.bench.cpp index 8738ca4..5d92bd8 100644 --- a/libcxx/test/benchmarks/containers/associative/unordered_multimap.bench.cpp +++ b/libcxx/test/benchmarks/containers/associative/unordered_multimap.bench.cpp @@ -23,6 +23,9 @@ struct support::adapt_operations<std::unordered_multimap<K, V>> { using InsertionResult = typename std::unordered_multimap<K, V>::iterator; static auto get_iterator(InsertionResult const& result) { return result; } + + template <class Allocator> + using rebind_alloc = std::unordered_multimap<K, V, std::hash<K>, std::equal_to<K>, Allocator>; }; int main(int argc, char** argv) { diff --git a/libcxx/test/benchmarks/containers/associative/unordered_multiset.bench.cpp b/libcxx/test/benchmarks/containers/associative/unordered_multiset.bench.cpp index 4888b01..09412fc 100644 --- a/libcxx/test/benchmarks/containers/associative/unordered_multiset.bench.cpp +++ b/libcxx/test/benchmarks/containers/associative/unordered_multiset.bench.cpp @@ -22,6 +22,9 @@ struct support::adapt_operations<std::unordered_multiset<K>> { using InsertionResult = typename std::unordered_multiset<K>::iterator; static auto get_iterator(InsertionResult const& result) { return result; } + + template <class Allocator> + using rebind_alloc = std::unordered_multiset<K, std::hash<K>, std::equal_to<K>, Allocator>; }; int main(int argc, char** argv) { diff --git a/libcxx/test/benchmarks/containers/associative/unordered_set.bench.cpp b/libcxx/test/benchmarks/containers/associative/unordered_set.bench.cpp index 89443a5..1b66633 100644 --- a/libcxx/test/benchmarks/containers/associative/unordered_set.bench.cpp +++ b/libcxx/test/benchmarks/containers/associative/unordered_set.bench.cpp @@ -24,6 +24,9 @@ struct support::adapt_operations<std::unordered_set<K>> { using InsertionResult = std::pair<typename std::unordered_set<K>::iterator, bool>; static auto get_iterator(InsertionResult const& result) { return result.first; } + + template <class Allocator> + using rebind_alloc = std::unordered_set<K, std::hash<K>, std::equal_to<K>, Allocator>; }; int main(int argc, char** argv) { diff --git a/libcxx/test/benchmarks/containers/string.bench.cpp b/libcxx/test/benchmarks/containers/string.bench.cpp index 2484ec8..98216d2 100644 --- a/libcxx/test/benchmarks/containers/string.bench.cpp +++ b/libcxx/test/benchmarks/containers/string.bench.cpp @@ -541,10 +541,7 @@ struct StringRead { static bool skip() { // Huge does not give us anything that Large doesn't have. Skip it. - if (Length() == ::Length::Huge) { - return true; - } - return false; + return Length() == ::Length::Huge; } std::string name() const { return "BM_StringRead" + Temperature::name() + Depth::name() + Length::name(); } @@ -585,14 +582,6 @@ void sanityCheckGeneratedStrings() { } } -// Some small codegen thunks to easily see generated code. -bool StringEqString(const std::string& a, const std::string& b) { return a == b; } -bool StringEqCStr(const std::string& a, const char* b) { return a == b; } -bool CStrEqString(const char* a, const std::string& b) { return a == b; } -bool StringEqCStrLiteralEmpty(const std::string& a) { return a == ""; } -bool StringEqCStrLiteralSmall(const std::string& a) { return a == SmallStringLiteral; } -bool StringEqCStrLiteralLarge(const std::string& a) { return a == LargeStringLiteral; } - int main(int argc, char** argv) { benchmark::Initialize(&argc, argv); if (benchmark::ReportUnrecognizedArguments(argc, argv)) @@ -615,16 +604,4 @@ int main(int argc, char** argv) { makeCartesianProductBenchmark<StringRelationalLiteral, AllRelations, AllLengths, AllLengths, AllDiffTypes>(); makeCartesianProductBenchmark<StringRead, AllTemperatures, AllDepths, AllLengths>(); benchmark::RunSpecifiedBenchmarks(); - - if (argc < 0) { - // ODR-use the functions to force them being generated in the binary. - auto functions = std::make_tuple( - StringEqString, - StringEqCStr, - CStrEqString, - StringEqCStrLiteralEmpty, - StringEqCStrLiteralSmall, - StringEqCStrLiteralLarge); - printf("%p", &functions); - } } diff --git a/libcxx/test/benchmarks/streams/fstream.bench.cpp b/libcxx/test/benchmarks/streams/ofstream.bench.cpp index 3ca1801..60606a9 100644 --- a/libcxx/test/benchmarks/streams/fstream.bench.cpp +++ b/libcxx/test/benchmarks/streams/ofstream.bench.cpp @@ -11,7 +11,7 @@ #include <benchmark/benchmark.h> -static void bm_ofstream_write(benchmark::State& state) { +static void bm_write(benchmark::State& state) { std::vector<char> buffer; buffer.resize(16384); @@ -20,24 +20,6 @@ static void bm_ofstream_write(benchmark::State& state) { for (auto _ : state) stream.write(buffer.data(), buffer.size()); } -BENCHMARK(bm_ofstream_write); - -static void bm_ifstream_read(benchmark::State& state) { - std::vector<char> buffer; - buffer.resize(16384); - - std::ofstream gen_testfile("testfile"); - gen_testfile.write(buffer.data(), buffer.size()); - - std::ifstream stream("testfile"); - assert(stream); - - for (auto _ : state) { - stream.read(buffer.data(), buffer.size()); - benchmark::DoNotOptimize(buffer); - stream.seekg(0); - } -} -BENCHMARK(bm_ifstream_read); +BENCHMARK(bm_write); BENCHMARK_MAIN(); diff --git a/libcxx/test/extensions/gnu/hash_map/copy.pass.cpp b/libcxx/test/extensions/gnu/hash_map/copy.pass.cpp new file mode 100644 index 0000000..65b8deb --- /dev/null +++ b/libcxx/test/extensions/gnu/hash_map/copy.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated + +// hash_map::hash_map(const hash_map&) + +#include <cassert> +#include <ext/hash_map> + +int main(int, char**) { + __gnu_cxx::hash_map<int, int> map; + + map.insert(std::make_pair(1, 1)); + map.insert(std::make_pair(2, 1)); + + auto map2 = map; + + assert(map2.size() == 2); + + return 0; +} diff --git a/libcxx/test/extensions/gnu/hash_set/copy.pass.cpp b/libcxx/test/extensions/gnu/hash_set/copy.pass.cpp new file mode 100644 index 0000000..95a3579 --- /dev/null +++ b/libcxx/test/extensions/gnu/hash_set/copy.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated + +// hash_set::hash_set(const hash_set&) + +#include <cassert> +#include <ext/hash_set> + +int main(int, char**) { + __gnu_cxx::hash_set<int> set; + + set.insert(1); + set.insert(2); + + auto set2 = set; + + assert(set2.size() == 2); + + return 0; +} diff --git a/libcxx/test/extensions/libcxx/odr_signature.assertion_semantics.sh.cpp b/libcxx/test/extensions/libcxx/odr_signature.assertion_semantics.sh.cpp new file mode 100644 index 0000000..8ec1ec8 --- /dev/null +++ b/libcxx/test/extensions/libcxx/odr_signature.assertion_semantics.sh.cpp @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// ABI tags have no effect in MSVC mode. +// XFAIL: msvc + +// Assertion semantics are not supported in C++03 mode and currently are experimental. +// UNSUPPORTED: c++03, libcpp-has-no-experimental-hardening-observe-semantic + +// Test that we encode the assertion semantic in an ABI tag to avoid ODR violations when linking TUs that have different +// values for it. + +// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU1 -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_IGNORE -o %t.tu1.o +// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU2 -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_OBSERVE -o %t.tu2.o +// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU3 -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE -o %t.tu3.o +// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU4 -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_ENFORCE -o %t.tu4.o +// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DMAIN -o %t.main.o +// RUN: %{cxx} %t.tu1.o %t.tu2.o %t.tu3.o %t.tu4.o %t.main.o %{flags} %{link_flags} -o %t.exe +// RUN: %{exec} %t.exe + +#include "test_macros.h" + +// `ignore` assertion semantic. +#ifdef TU1 +# include <__config> +_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 1; } +int tu1() { return f(); } +#endif // TU1 + +// `observe` assertion semantic. +#ifdef TU2 +# include <__config> +_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 2; } +int tu2() { return f(); } +#endif // TU2 + +// `quick-enforce` assertion semantic. +#ifdef TU3 +# include <__config> +_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 3; } +int tu3() { return f(); } +#endif // TU3 + +// `enforce` assertion semantic. +#ifdef TU4 +# include <__config> +_LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 4; } +int tu4() { return f(); } +#endif // TU4 + +#ifdef MAIN +# include <cassert> + +int tu1(); +int tu2(); +int tu3(); +int tu4(); + +int main(int, char**) { + assert(tu1() == 1); + assert(tu2() == 2); + assert(tu3() == 3); + assert(tu4() == 4); + return 0; +} +#endif // MAIN diff --git a/libcxx/test/extensions/libcxx/odr_signature.exceptions.sh.cpp b/libcxx/test/extensions/libcxx/odr_signature.exceptions.sh.cpp index c0ba48e..61aaf4f 100644 --- a/libcxx/test/extensions/libcxx/odr_signature.exceptions.sh.cpp +++ b/libcxx/test/extensions/libcxx/odr_signature.exceptions.sh.cpp @@ -9,8 +9,6 @@ // ABI tags have no effect in MSVC mode. // XFAIL: msvc -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - // Test that we encode whether exceptions are supported in an ABI tag to avoid // ODR violations when linking TUs that have different values for it. @@ -24,14 +22,14 @@ // -fno-exceptions #ifdef TU1 -# include <__config> +# include <version> _LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 1; } int tu1() { return f(); } #endif // TU1 // -fexceptions #ifdef TU2 -# include <__config> +# include <version> _LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 2; } int tu2() { return f(); } #endif // TU2 diff --git a/libcxx/test/extensions/libcxx/odr_signature.hardening.sh.cpp b/libcxx/test/extensions/libcxx/odr_signature.hardening.sh.cpp index 8daf3f3..28647d7 100644 --- a/libcxx/test/extensions/libcxx/odr_signature.hardening.sh.cpp +++ b/libcxx/test/extensions/libcxx/odr_signature.hardening.sh.cpp @@ -9,8 +9,6 @@ // ABI tags have no effect in MSVC mode. // XFAIL: msvc -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - // Test that we encode the hardening mode in an ABI tag to avoid ODR violations // when linking TUs that have different values for it. @@ -27,28 +25,28 @@ // fast hardening mode #ifdef TU1 -# include <__config> +# include <version> _LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 1; } int tu1() { return f(); } #endif // TU1 // extensive hardening mode #ifdef TU2 -# include <__config> +# include <version> _LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 2; } int tu2() { return f(); } #endif // TU2 // debug hardening mode #ifdef TU3 -# include <__config> +# include <version> _LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 3; } int tu3() { return f(); } #endif // TU3 // No hardening #ifdef TU4 -# include <__config> +# include <version> _LIBCPP_HIDE_FROM_ABI TEST_NOINLINE inline int f() { return 4; } int tu4() { return f(); } #endif // TU4 diff --git a/libcxx/test/libcxx-03/algorithms/half_positive.pass.cpp b/libcxx/test/libcxx-03/algorithms/half_positive.pass.cpp index 292fcf3..ad0cac2 100644 --- a/libcxx/test/libcxx-03/algorithms/half_positive.pass.cpp +++ b/libcxx/test/libcxx-03/algorithms/half_positive.pass.cpp @@ -41,17 +41,5 @@ int main(int, char**) #endif // !defined(TEST_HAS_NO_INT128) } -#if TEST_STD_VER >= 11 - { - static_assert(test<char>(), ""); - static_assert(test<int>(), ""); - static_assert(test<long>(), ""); - static_assert(test<std::size_t>(), ""); -#if !defined(TEST_HAS_NO_INT128) - static_assert(test<__int128_t>(), ""); -#endif // !defined(TEST_HAS_NO_INT128) - } -#endif // TEST_STD_VER >= 11 - return 0; } diff --git a/libcxx/test/libcxx-03/algorithms/robust_against_copying_comparators.pass.cpp b/libcxx/test/libcxx-03/algorithms/robust_against_copying_comparators.pass.cpp index 2562516..2e3fc6d 100644 --- a/libcxx/test/libcxx-03/algorithms/robust_against_copying_comparators.pass.cpp +++ b/libcxx/test/libcxx-03/algorithms/robust_against_copying_comparators.pass.cpp @@ -82,17 +82,6 @@ struct BinaryTransform { TEST_CONSTEXPR T operator()(T, T) const { return 0; } }; -#if TEST_STD_VER > 17 -template <class T> -struct ThreeWay { - int* copies_; - constexpr explicit ThreeWay(int* copies) : copies_(copies) {} - constexpr ThreeWay(const ThreeWay& rhs) : copies_(rhs.copies_) { *copies_ += 1; } - constexpr ThreeWay& operator=(const ThreeWay&) = default; - constexpr std::strong_ordering operator()(T, T) const { return std::strong_ordering::equal; } -}; -#endif - template <class T> TEST_CONSTEXPR_CXX20 bool all_the_algorithms() { T a[10] = {}; @@ -109,28 +98,14 @@ TEST_CONSTEXPR_CXX20 bool all_the_algorithms() { int copies = 0; (void)std::adjacent_find(first, last, Equal<T>(&copies)); assert(copies == 0); -#if TEST_STD_VER >= 11 - (void)std::all_of(first, last, UnaryTrue<T>(&copies)); - assert(copies == 0); - (void)std::any_of(first, last, UnaryTrue<T>(&copies)); - assert(copies == 0); -#endif (void)std::binary_search(first, last, value, Less<T>(&copies)); assert(copies == 0); -#if TEST_STD_VER > 17 - (void)std::clamp(value, value, value, Less<T>(&copies)); - assert(copies == 0); -#endif (void)std::count_if(first, last, UnaryTrue<T>(&copies)); assert(copies == 0); (void)std::copy_if(first, last, first2, UnaryTrue<T>(&copies)); assert(copies == 0); (void)std::equal(first, last, first2, Equal<T>(&copies)); assert(copies == 0); -#if TEST_STD_VER > 11 - (void)std::equal(first, last, first2, last2, Equal<T>(&copies)); - assert(copies == 0); -#endif (void)std::equal_range(first, last, value, Less<T>(&copies)); assert(copies == 0); (void)std::find_end(first, last, first2, mid2, Equal<T>(&copies)); @@ -144,10 +119,6 @@ TEST_CONSTEXPR_CXX20 bool all_the_algorithms() { (void)std::for_each(first, last, UnaryVoid<T>(&copies)); assert(copies == 1); copies = 0; -#if TEST_STD_VER > 14 - (void)std::for_each_n(first, count, UnaryVoid<T>(&copies)); - assert(copies == 0); -#endif (void)std::generate(first, last, NullaryValue<T>(&copies)); assert(copies == 0); (void)std::generate_n(first, count, NullaryValue<T>(&copies)); @@ -162,10 +133,6 @@ TEST_CONSTEXPR_CXX20 bool all_the_algorithms() { assert(copies == 0); (void)std::is_permutation(first, last, first2, Equal<T>(&copies)); assert(copies == 0); -#if TEST_STD_VER > 11 - (void)std::is_permutation(first, last, first2, last2, Equal<T>(&copies)); - assert(copies == 0); -#endif (void)std::is_sorted(first, last, Less<T>(&copies)); assert(copies == 0); (void)std::is_sorted_until(first, last, Less<T>(&copies)); @@ -176,52 +143,28 @@ TEST_CONSTEXPR_CXX20 bool all_the_algorithms() { } (void)std::lexicographical_compare(first, last, first2, last2, Less<T>(&copies)); assert(copies == 0); -#if TEST_STD_VER > 17 - (void)std::lexicographical_compare_three_way(first, last, first2, last2, ThreeWay<T>(&copies)); - assert(copies == 0); -#endif (void)std::lower_bound(first, last, value, Less<T>(&copies)); assert(copies == 0); (void)std::make_heap(first, last, Less<T>(&copies)); assert(copies == 0); (void)std::max(value, value, Less<T>(&copies)); assert(copies == 0); -#if TEST_STD_VER >= 11 - (void)std::max({value, value}, Less<T>(&copies)); - assert(copies == 0); -#endif (void)std::max_element(first, last, Less<T>(&copies)); assert(copies == 0); (void)std::merge(first, mid, mid, last, first2, Less<T>(&copies)); assert(copies == 0); (void)std::min(value, value, Less<T>(&copies)); assert(copies == 0); -#if TEST_STD_VER >= 11 - (void)std::min({value, value}, Less<T>(&copies)); - assert(copies == 0); -#endif (void)std::min_element(first, last, Less<T>(&copies)); assert(copies == 0); (void)std::minmax(value, value, Less<T>(&copies)); assert(copies == 0); -#if TEST_STD_VER >= 11 - (void)std::minmax({value, value}, Less<T>(&copies)); - assert(copies == 0); -#endif (void)std::minmax_element(first, last, Less<T>(&copies)); assert(copies == 0); (void)std::mismatch(first, last, first2, Equal<T>(&copies)); assert(copies == 0); -#if TEST_STD_VER > 11 - (void)std::mismatch(first, last, first2, last2, Equal<T>(&copies)); - assert(copies == 0); -#endif (void)std::next_permutation(first, last, Less<T>(&copies)); assert(copies == 0); -#if TEST_STD_VER >= 11 - (void)std::none_of(first, last, UnaryTrue<T>(&copies)); - assert(copies == 0); -#endif (void)std::nth_element(first, mid, last, Less<T>(&copies)); assert(copies == 0); (void)std::partial_sort(first, mid, last, Less<T>(&copies)); @@ -299,14 +242,6 @@ bool test_segmented_iterator() { assert(copies == 1); copies = 0; -#if TEST_STD_VER >= 20 - std::vector<std::vector<int>> vecs(3, std::vector<int>(10)); - auto v = std::views::join(vecs); - (void)std::for_each(v.begin(), v.end(), UnaryVoid<int>(&copies)); - assert(copies == 1); - copies = 0; -#endif - return true; } @@ -314,10 +249,6 @@ int main(int, char**) { all_the_algorithms<void*>(); all_the_algorithms<int>(); assert(test_segmented_iterator()); -#if TEST_STD_VER > 17 - static_assert(all_the_algorithms<void*>()); - static_assert(all_the_algorithms<int>()); -#endif return 0; } diff --git a/libcxx/test/libcxx-03/algorithms/robust_against_cpp20_hostile_iterators.compile.pass.cpp b/libcxx/test/libcxx-03/algorithms/robust_against_cpp20_hostile_iterators.compile.pass.cpp index 03fef57..009a234 100644 --- a/libcxx/test/libcxx-03/algorithms/robust_against_cpp20_hostile_iterators.compile.pass.cpp +++ b/libcxx/test/libcxx-03/algorithms/robust_against_cpp20_hostile_iterators.compile.pass.cpp @@ -99,10 +99,6 @@ void test() { (void) std::equal_range(it, it, 0, pred); (void) std::equal(it, it, it); (void) std::equal(it, it, it, pred); -#if TEST_STD_VER > 11 - (void) std::equal(it, it, it, it); - (void) std::equal(it, it, it, it, pred); -#endif (void) std::fill_n(it, 0, 0); (void) std::fill(it, it, 0); (void) std::find_end(it, it, it, it); @@ -112,9 +108,6 @@ void test() { (void) std::find_if_not(it, it, pred); (void) std::find_if(it, it, pred); (void) std::find(it, it, 0); -#if TEST_STD_VER > 14 - (void) std::for_each_n(it, 0, pred); -#endif (void) std::for_each(it, it, pred); (void) std::generate_n(it, 0, pred); (void) std::generate(it, it, pred); @@ -129,20 +122,12 @@ void test() { (void) std::is_partitioned(it, it, pred); (void) std::is_permutation(it, it, it); (void) std::is_permutation(it, it, it, pred); -#if TEST_STD_VER > 11 - (void) std::is_permutation(it, it, it, it); - (void) std::is_permutation(it, it, it, it, pred); -#endif (void) std::is_sorted_until(it, it); (void) std::is_sorted_until(it, it, pred); (void) std::is_sorted(it, it); (void) std::is_sorted(it, it, pred); (void) std::lexicographical_compare(it, it, it, it); (void) std::lexicographical_compare(it, it, it, it, pred); -#if TEST_STD_VER > 17 - (void)std::lexicographical_compare_three_way(it, it, it, it); - (void)std::lexicographical_compare_three_way(it, it, it, it, std::compare_three_way()); -#endif (void) std::lower_bound(it, it, 0); (void) std::lower_bound(it, it, 0, pred); (void) std::make_heap(it, it); @@ -189,14 +174,8 @@ void test() { (void) std::reverse(it, it); (void) std::rotate_copy(it, it, it, it); (void) std::rotate(it, it, it); -#if TEST_STD_VER > 14 - (void) std::sample(it, it, it, 0, rng); -#endif (void) std::search(it, it, it, it); (void) std::search(it, it, it, it, pred); -#if TEST_STD_VER > 14 - (void) std::search(it, it, std::default_searcher<Cpp20HostileIterator<int*>>(it, it)); -#endif (void) std::set_difference(it, it, it, it, it); (void) std::set_difference(it, it, it, it, it, pred); (void) std::set_intersection(it, it, it, it, it); @@ -205,10 +184,6 @@ void test() { (void) std::set_symmetric_difference(it, it, it, it, it, pred); (void) std::set_union(it, it, it, it, it); (void) std::set_union(it, it, it, it, it, pred); -#if TEST_STD_VER > 17 - (void) std::shift_left(it, it, 0); - (void) std::shift_right(it, it, 0); -#endif (void) std::shuffle(it, it, rng); (void) std::sort_heap(it, it); (void) std::sort_heap(it, it, pred); diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/asan.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/asan.pass.cpp index 03d2b3e6..72875a5 100644 --- a/libcxx/test/libcxx-03/containers/sequences/vector/asan.pass.cpp +++ b/libcxx/test/libcxx-03/containers/sequences/vector/asan.pass.cpp @@ -26,29 +26,6 @@ extern "C" void __sanitizer_set_death_callback(void (*callback)(void)); void do_exit() { exit(0); } int main(int, char**) { -#if TEST_STD_VER >= 11 - { - typedef int T; - typedef cpp17_input_iterator<T*> MyInputIter; - std::vector<T, min_allocator<T>> v; - v.reserve(1); - int i[] = {42}; - v.insert(v.begin(), MyInputIter(i), MyInputIter(i + 1)); - assert(v[0] == 42); - assert(is_contiguous_container_asan_correct(v)); - } - { - typedef char T; - typedef cpp17_input_iterator<T*> MyInputIter; - std::vector<T, unaligned_allocator<T>> v; - v.reserve(1); - char i[] = {'a', 'b'}; - v.insert(v.begin(), MyInputIter(i), MyInputIter(i + 2)); - assert(v[0] == 'a'); - assert(v[1] == 'b'); - assert(is_contiguous_container_asan_correct(v)); - } -#endif // TEST_STD_VER >= 11 { typedef cpp17_input_iterator<int*> MyInputIter; // Sould not trigger ASan. diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/asan_throw.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/asan_throw.pass.cpp index dcfa802..c18242a 100644 --- a/libcxx/test/libcxx-03/containers/sequences/vector/asan_throw.pass.cpp +++ b/libcxx/test/libcxx-03/containers/sequences/vector/asan_throw.pass.cpp @@ -68,23 +68,6 @@ void test_push_back() { assert(is_contiguous_container_asan_correct(v)); } -void test_emplace_back() { -#if TEST_STD_VER >= 11 - std::vector<X> v; - v.reserve(2); - v.push_back(X(2)); - assert(v.size() == 1); - try { - v.emplace_back(42); - assert(0); - } catch (int e) { - assert(v.size() == 1); - } - assert(v.size() == 1); - assert(is_contiguous_container_asan_correct(v)); -#endif -} - void test_insert_range() { std::vector<X> v; v.reserve(4); @@ -119,24 +102,6 @@ void test_insert() { assert(is_contiguous_container_asan_correct(v)); } -void test_emplace() { -#if TEST_STD_VER >= 11 - std::vector<X> v; - v.reserve(3); - v.insert(v.end(), X(1)); - v.insert(v.begin(), X(2)); - assert(v.size() == 2); - try { - v.emplace(v.end(), 42); - assert(0); - } catch (int e) { - assert(v.size() == 2); - } - assert(v.size() == 2); - assert(is_contiguous_container_asan_correct(v)); -#endif -} - void test_insert_range2() { std::vector<X> v; v.reserve(4); @@ -219,10 +184,8 @@ void test_resize_param() { int main(int, char**) { test_push_back(); - test_emplace_back(); test_insert_range(); test_insert(); - test_emplace(); test_insert_range2(); test_insert_n(); test_insert_n2(); diff --git a/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/construct.cxx20.pass.cpp b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/construct.cxx20.pass.cpp index 9a37cf8..4e1cda5 100644 --- a/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/construct.cxx20.pass.cpp +++ b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/construct.cxx20.pass.cpp @@ -38,24 +38,6 @@ struct A { int move_only_constructed = 0; -#if TEST_STD_VER >= 11 -class move_only { - move_only(const move_only&) = delete; - move_only& operator=(const move_only&) = delete; - -public: - move_only(move_only&&) { ++move_only_constructed; } - move_only& operator=(move_only&&) { return *this; } - - move_only() { ++move_only_constructed; } - ~move_only() { --move_only_constructed; } - -public: - int data; // unused other than to make sizeof(move_only) == sizeof(int). - // but public to suppress "-Wunused-private-field" -}; -#endif // TEST_STD_VER >= 11 - int main(int, char**) { globalMemCounter.reset(); { @@ -107,41 +89,6 @@ int main(int, char**) { assert(globalMemCounter.checkOutstandingNewEq(0)); assert(A_constructed == 0); } -#if TEST_STD_VER >= 11 - { - std::allocator<move_only> a; - assert(globalMemCounter.checkOutstandingNewEq(0)); - assert(move_only_constructed == 0); - - globalMemCounter.last_new_size = 0; - move_only* ap = a.allocate(3); - DoNotOptimize(ap); - assert(globalMemCounter.checkOutstandingNewEq(1)); - assert(globalMemCounter.checkLastNewSizeEq(3 * sizeof(int))); - assert(move_only_constructed == 0); - - a.construct(ap); - assert(globalMemCounter.checkOutstandingNewEq(1)); - assert(move_only_constructed == 1); - - a.destroy(ap); - assert(globalMemCounter.checkOutstandingNewEq(1)); - assert(move_only_constructed == 0); - - a.construct(ap, move_only()); - assert(globalMemCounter.checkOutstandingNewEq(1)); - assert(move_only_constructed == 1); - - a.destroy(ap); - assert(globalMemCounter.checkOutstandingNewEq(1)); - assert(move_only_constructed == 0); - - a.deallocate(ap, 3); - DoNotOptimize(ap); - assert(globalMemCounter.checkOutstandingNewEq(0)); - assert(move_only_constructed == 0); - } -#endif return 0; } diff --git a/libcxx/test/libcxx-03/input.output/string.streams/stringbuf/const_sso_buffer.pass.cpp b/libcxx/test/libcxx-03/input.output/string.streams/stringbuf/const_sso_buffer.pass.cpp index d6caa33..b6cc6e50 100644 --- a/libcxx/test/libcxx-03/input.output/string.streams/stringbuf/const_sso_buffer.pass.cpp +++ b/libcxx/test/libcxx-03/input.output/string.streams/stringbuf/const_sso_buffer.pass.cpp @@ -20,7 +20,6 @@ #include <cassert> #include "test_macros.h" -#include "min_allocator.h" template <class CharT> struct test_buf : public std::basic_stringbuf<CharT> { @@ -40,29 +39,6 @@ struct test_buf : public std::basic_stringbuf<CharT> { explicit test_buf(std::ios_base::openmode which) : std::basic_stringbuf<CharT>(which) {} explicit test_buf(const std::basic_string<CharT>& s) : std::basic_stringbuf<CharT>(s) {} -#if TEST_STD_VER >= 20 - explicit test_buf(const std::allocator<CharT>& a) : std::basic_stringbuf<CharT>(a) {} - test_buf(std::ios_base::openmode which, const std::allocator<CharT>& a) : std::basic_stringbuf<CharT>(which, a) {} - explicit test_buf(std::basic_string<CharT>&& s) - : std::basic_stringbuf<CharT>(std::forward<std::basic_string<CharT>>(s)) {} - - test_buf(const std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>>& s, - const std::allocator<CharT>& a) - : std::basic_stringbuf<CharT>(s, a) {} - test_buf(const std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>>& s, - std::ios_base::openmode which, - const std::allocator<CharT>& a) - : std::basic_stringbuf<CharT>(s, which, a) {} - test_buf(const std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>>& s) - : std::basic_stringbuf<CharT>(s) {} -#endif // TEST_STD_VER >= 20 - -#if TEST_STD_VER >= 26 - test_buf(std::basic_string_view<CharT> s) : std::basic_stringbuf<CharT>(s) {} - test_buf(std::basic_string_view<CharT> s, const std::allocator<CharT>& a) : std::basic_stringbuf<CharT>(s, a) {} - test_buf(std::basic_string_view<CharT> s, std::ios_base::openmode which, const std::allocator<CharT>& a) - : std::basic_stringbuf<CharT>(s, which, a) {} -#endif // TEST_STD_VER >= 26 }; template <class CharT> @@ -88,76 +64,6 @@ static void test() { assert(b.pptr() == b.pbase()); assert(b.epptr() == b.pbase() + size); // copy so uses size } -#if TEST_STD_VER >= 20 - { - test_buf<CharT> b = test_buf<CharT>(std::allocator<CharT>()); - assert(b.pbase() != nullptr); - assert(b.pptr() == b.pbase()); - assert(b.epptr() == b.pbase() + size); - } - { - test_buf<CharT> b = test_buf<CharT>(std::ios_base::out, std::allocator<CharT>()); - assert(b.pbase() != nullptr); - assert(b.pptr() == b.pbase()); - assert(b.epptr() == b.pbase() + size); - } - { - std::basic_string<CharT> s; - s.reserve(1024); - std::size_t capacity = s.capacity(); - test_buf<CharT> b = test_buf<CharT>(std::move(s)); - assert(b.pbase() != nullptr); - assert(b.pptr() == b.pbase()); - assert(b.epptr() >= b.pbase() + capacity); // move so uses s.capacity() - } - { - std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>> s; - s.reserve(1024); - test_buf<CharT> b = test_buf<CharT>(s, std::allocator<CharT>()); - assert(b.pbase() != nullptr); - assert(b.pptr() == b.pbase()); - assert(b.epptr() == b.pbase() + size); // copy so uses size - } - { - std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>> s; - s.reserve(1024); - test_buf<CharT> b = test_buf<CharT>(s, std::ios_base::out, std::allocator<CharT>()); - assert(b.pbase() != nullptr); - assert(b.pptr() == b.pbase()); - assert(b.epptr() == b.pbase() + size); // copy so uses size - } - { - std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>> s; - s.reserve(1024); - test_buf<CharT> b = test_buf<CharT>(s); - assert(b.pbase() != nullptr); - assert(b.pptr() == b.pbase()); - assert(b.epptr() == b.pbase() + size); // copy so uses size - } -#endif // TEST_STD_VER >= 20 -#if TEST_STD_VER >= 26 - { - std::basic_string_view<CharT> s; - test_buf<CharT> b = test_buf<CharT>(s); - assert(b.pbase() != nullptr); - assert(b.pptr() == b.pbase()); - assert(b.epptr() == b.pbase() + size); - } - { - std::basic_string_view<CharT> s; - test_buf<CharT> b = test_buf<CharT>(s, std::allocator<CharT>()); - assert(b.pbase() != nullptr); - assert(b.pptr() == b.pbase()); - assert(b.epptr() == b.pbase() + size); - } - { - std::basic_string_view<CharT> s; - test_buf<CharT> b = test_buf<CharT>(s, std::ios_base::out, std::allocator<CharT>()); - assert(b.pbase() != nullptr); - assert(b.pptr() == b.pbase()); - assert(b.epptr() == b.pbase() + size); - } -#endif // TEST_STD_VER >= 26 } int main(int, char**) { diff --git a/libcxx/test/libcxx-03/iterators/bounded_iter/arithmetic.pass.cpp b/libcxx/test/libcxx-03/iterators/bounded_iter/arithmetic.pass.cpp index b4b6e7f..b5b6916 100644 --- a/libcxx/test/libcxx-03/iterators/bounded_iter/arithmetic.pass.cpp +++ b/libcxx/test/libcxx-03/iterators/bounded_iter/arithmetic.pass.cpp @@ -99,14 +99,6 @@ TEST_CONSTEXPR_CXX14 bool tests() { int main(int, char**) { tests<int*>(); -#if TEST_STD_VER > 11 - static_assert(tests<int*>(), ""); -#endif - -#if TEST_STD_VER > 17 - tests<contiguous_iterator<int*> >(); - static_assert(tests<contiguous_iterator<int*> >(), ""); -#endif return 0; } diff --git a/libcxx/test/libcxx-03/iterators/bounded_iter/comparison.pass.cpp b/libcxx/test/libcxx-03/iterators/bounded_iter/comparison.pass.cpp index 490bfed..9c6ce28 100644 --- a/libcxx/test/libcxx-03/iterators/bounded_iter/comparison.pass.cpp +++ b/libcxx/test/libcxx-03/iterators/bounded_iter/comparison.pass.cpp @@ -60,28 +60,11 @@ TEST_CONSTEXPR_CXX14 bool tests() { assert(iter1 >= iter1); } -#if TEST_STD_VER >= 20 - // P1614 - std::same_as<std::strong_ordering> decltype(auto) r1 = iter1 <=> iter2; - assert(r1 == std::strong_ordering::less); -#endif - return true; } int main(int, char**) { tests<int*>(); -#if TEST_STD_VER > 11 - static_assert(tests<int*>(), ""); -#endif - -#if TEST_STD_VER > 17 - tests<contiguous_iterator<int*>>(); - static_assert(tests<contiguous_iterator<int*>>()); - - tests<three_way_contiguous_iterator<int*>>(); - static_assert(tests<three_way_contiguous_iterator<int*>>()); -#endif return 0; } diff --git a/libcxx/test/libcxx-03/iterators/bounded_iter/pointer_traits.pass.cpp b/libcxx/test/libcxx-03/iterators/bounded_iter/pointer_traits.pass.cpp index 671e716..fe21529 100644 --- a/libcxx/test/libcxx-03/iterators/bounded_iter/pointer_traits.pass.cpp +++ b/libcxx/test/libcxx-03/iterators/bounded_iter/pointer_traits.pass.cpp @@ -37,10 +37,6 @@ TEST_CONSTEXPR_CXX14 bool tests() { std::__bounded_iter<Iter> const iter2 = std::__make_bounded_iter(Iter(e), Iter(b), Iter(e)); assert(std::__to_address(iter1) == b); // in-bounds iterator assert(std::__to_address(iter2) == e); // out-of-bounds iterator -#if TEST_STD_VER > 17 - assert(std::to_address(iter1) == b); // in-bounds iterator - assert(std::to_address(iter2) == e); // out-of-bounds iterator -#endif } return true; @@ -48,14 +44,6 @@ TEST_CONSTEXPR_CXX14 bool tests() { int main(int, char**) { tests<int*>(); -#if TEST_STD_VER > 11 - static_assert(tests<int*>(), ""); -#endif - -#if TEST_STD_VER > 17 - tests<contiguous_iterator<int*> >(); - static_assert(tests<contiguous_iterator<int*> >(), ""); -#endif return 0; } diff --git a/libcxx/test/libcxx-03/iterators/bounded_iter/types.compile.pass.cpp b/libcxx/test/libcxx-03/iterators/bounded_iter/types.compile.pass.cpp index 0d27dff..43c53a0 100644 --- a/libcxx/test/libcxx-03/iterators/bounded_iter/types.compile.pass.cpp +++ b/libcxx/test/libcxx-03/iterators/bounded_iter/types.compile.pass.cpp @@ -18,32 +18,9 @@ #include "test_macros.h" -#if TEST_STD_VER > 17 -struct Iterator { - struct value_type {}; - using difference_type = int; - struct pointer {}; - using reference = value_type&; - struct iterator_category : std::random_access_iterator_tag {}; - using iterator_concept = std::contiguous_iterator_tag; -}; - -using BoundedIter1 = std::__bounded_iter<Iterator>; -static_assert(std::is_same<BoundedIter1::value_type, Iterator::value_type>::value, ""); -static_assert(std::is_same<BoundedIter1::difference_type, Iterator::difference_type>::value, ""); -static_assert(std::is_same<BoundedIter1::pointer, Iterator::pointer>::value, ""); -static_assert(std::is_same<BoundedIter1::reference, Iterator::reference>::value, ""); -static_assert(std::is_same<BoundedIter1::iterator_category, Iterator::iterator_category>::value, ""); -static_assert(std::is_same<BoundedIter1::iterator_concept, Iterator::iterator_concept>::value, ""); -#endif - - using BoundedIter2 = std::__bounded_iter<int*>; static_assert(std::is_same<BoundedIter2::value_type, int>::value, ""); static_assert(std::is_same<BoundedIter2::difference_type, std::ptrdiff_t>::value, ""); static_assert(std::is_same<BoundedIter2::pointer, int*>::value, ""); static_assert(std::is_same<BoundedIter2::reference, int&>::value, ""); static_assert(std::is_same<BoundedIter2::iterator_category, std::random_access_iterator_tag>::value, ""); -#if TEST_STD_VER > 17 -static_assert(std::is_same<BoundedIter2::iterator_concept, std::contiguous_iterator_tag>::value, ""); -#endif diff --git a/libcxx/test/libcxx-03/iterators/contiguous_iterators.conv.compile.pass.cpp b/libcxx/test/libcxx-03/iterators/contiguous_iterators.conv.compile.pass.cpp index 4d36909..3e9707a 100644 --- a/libcxx/test/libcxx-03/iterators/contiguous_iterators.conv.compile.pass.cpp +++ b/libcxx/test/libcxx-03/iterators/contiguous_iterators.conv.compile.pass.cpp @@ -54,12 +54,3 @@ static_assert(!std::is_constructible<std::vector<Base>::iterator, std::vector<De static_assert(!std::is_constructible<std::vector<Base>::const_iterator, std::vector<Derived>::iterator>::value, ""); static_assert(!std::is_constructible<std::vector<Base>::const_iterator, std::vector<Derived>::const_iterator>::value, ""); - -#if TEST_STD_VER >= 20 -static_assert(!std::is_convertible_v<std::span<Derived>::iterator, std::span<Base>::iterator>); -static_assert(!std::is_convertible_v<std::span<Derived>::iterator, std::span<const Base>::iterator>); -static_assert(!std::is_convertible_v<std::span<const Derived>::iterator, std::span<Base>::iterator>); -static_assert(!std::is_constructible_v<std::span<Base>::iterator, std::span<Derived>::iterator>); -static_assert(!std::is_constructible_v<std::span<Base>::iterator, std::span<const Derived>::iterator>); -static_assert(!std::is_constructible_v<std::span<const Base>::iterator, std::span<const Derived>::iterator>); -#endif diff --git a/libcxx/test/libcxx-03/iterators/contiguous_iterators.pass.cpp b/libcxx/test/libcxx-03/iterators/contiguous_iterators.pass.cpp index f00ca4e..56f12e0 100644 --- a/libcxx/test/libcxx-03/iterators/contiguous_iterators.pass.cpp +++ b/libcxx/test/libcxx-03/iterators/contiguous_iterators.pass.cpp @@ -27,14 +27,6 @@ #include "test_macros.h" #include "test_iterators.h" -#if TEST_STD_VER >= 17 -#include <string_view> -#endif - -#if TEST_STD_VER >= 20 -#include <span> -#endif - class T; // incomplete class my_input_iterator @@ -94,59 +86,12 @@ public: friend bool operator>=(const Self&, const Self&); }; -#if TEST_STD_VER >= 20 -class my_contiguous_iterator -{ - struct tag : std::contiguous_iterator_tag {}; - typedef my_contiguous_iterator Self; - int *state_; -public: - typedef tag iterator_category; - typedef int value_type; - typedef int difference_type; - typedef int* pointer; - typedef int& reference; - typedef int element_type; // enable to_address via pointer_traits - - my_contiguous_iterator(); - reference operator*() const; - pointer operator->() const; - reference operator[](difference_type) const; - - Self& operator++(); - Self operator++(int); - Self& operator--(); - Self operator--(int); - friend Self& operator+=(Self&, difference_type); - friend Self& operator-=(Self&, difference_type); - friend Self operator+(Self, difference_type); - friend Self operator+(difference_type, Self); - friend Self operator-(Self, difference_type); - friend difference_type operator-(Self, Self); - friend bool operator==(const Self&, const Self&); - friend bool operator!=(const Self&, const Self&); - friend bool operator<(const Self&, const Self&); - friend bool operator>(const Self&, const Self&); - friend bool operator<=(const Self&, const Self&); - friend bool operator>=(const Self&, const Self&); -}; -#endif - struct fake_deque_iterator : std::deque<int>::iterator { using element_type = int; }; static_assert(std::__has_random_access_iterator_category<fake_deque_iterator>::value, ""); static_assert(!std::__libcpp_is_contiguous_iterator<fake_deque_iterator>::value, ""); -#if TEST_STD_VER >= 20 -struct fake2_deque_iterator : std::deque<int>::iterator { - using iterator_concept = std::contiguous_iterator_tag; - using element_type = int; -}; -static_assert(std::__has_random_access_iterator_category<fake2_deque_iterator>::value, ""); -static_assert(std::__libcpp_is_contiguous_iterator<fake2_deque_iterator>::value, ""); -#endif - int main(int, char**) { // basic tests @@ -158,9 +103,6 @@ int main(int, char**) static_assert((!std::__libcpp_is_contiguous_iterator<my_input_iterator>::value), ""); static_assert((!std::__libcpp_is_contiguous_iterator<my_random_access_iterator>::value), ""); -#if TEST_STD_VER >= 20 - static_assert(( std::__libcpp_is_contiguous_iterator<my_contiguous_iterator>::value), ""); -#endif // move_iterator changes value category, which makes it pretty sketchy to use in optimized codepaths static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<char *> >::value), ""); @@ -168,18 +110,12 @@ int main(int, char**) static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<int *> >::value), ""); static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<T *> >::value), ""); static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<my_random_access_iterator> >::value), ""); -#if TEST_STD_VER >= 20 - static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<my_contiguous_iterator> >::value), ""); -#endif static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<char *> >::value), ""); static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<const char *> >::value), ""); static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<int *> >::value), ""); static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<T *> >::value), ""); static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<my_random_access_iterator> >::value), ""); -#if TEST_STD_VER >= 20 - static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<my_contiguous_iterator> >::value), ""); -#endif static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<char *> >::value), ""); static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<const char *> >::value), ""); @@ -192,20 +128,12 @@ int main(int, char**) static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<my_random_access_iterator> >::value), ""); static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<std::__wrap_iter<my_random_access_iterator> > >::value), ""); -#if TEST_STD_VER >= 20 - static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<my_contiguous_iterator> >::value), ""); - static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<std::__wrap_iter<my_contiguous_iterator> > >::value), ""); -#endif - // iterators in the libc++ test suite static_assert((!std::__libcpp_is_contiguous_iterator<cpp17_output_iterator <char *> >::value), ""); static_assert((!std::__libcpp_is_contiguous_iterator<cpp17_input_iterator <char *> >::value), ""); static_assert((!std::__libcpp_is_contiguous_iterator<forward_iterator <char *> >::value), ""); static_assert((!std::__libcpp_is_contiguous_iterator<bidirectional_iterator<char *> >::value), ""); static_assert((!std::__libcpp_is_contiguous_iterator<random_access_iterator<char *> >::value), ""); -#if TEST_STD_VER >= 20 - static_assert(( std::__libcpp_is_contiguous_iterator<contiguous_iterator <char *> >::value), ""); -#endif static_assert((!std::__libcpp_is_contiguous_iterator<ThrowingIterator <char *> >::value), ""); static_assert((!std::__libcpp_is_contiguous_iterator<NonThrowingIterator <char *> >::value), ""); @@ -244,22 +172,5 @@ int main(int, char**) static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<bool>::reverse_iterator> ::value), ""); static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<bool>::const_reverse_iterator> ::value), ""); -#if TEST_STD_VER >= 11 - static_assert(( std::__libcpp_is_contiguous_iterator<std::initializer_list<int>::iterator> ::value), ""); - static_assert(( std::__libcpp_is_contiguous_iterator<std::initializer_list<int>::const_iterator>::value), ""); -#endif - -#if TEST_STD_VER >= 17 - static_assert(( std::__libcpp_is_contiguous_iterator<std::string_view::iterator> ::value), ""); - static_assert(( std::__libcpp_is_contiguous_iterator<std::string_view::const_iterator>::value), ""); -#endif - -#if TEST_STD_VER >= 20 - static_assert(( std::__libcpp_is_contiguous_iterator<std::span< int>::iterator> ::value), ""); - static_assert((!std::__libcpp_is_contiguous_iterator<std::span< int>::reverse_iterator>::value), ""); - static_assert(( std::__libcpp_is_contiguous_iterator<std::span<const int>::iterator> ::value), ""); - static_assert((!std::__libcpp_is_contiguous_iterator<std::span<const int>::reverse_iterator>::value), ""); -#endif - return 0; } diff --git a/libcxx/test/libcxx-03/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/get_container.pass.cpp b/libcxx/test/libcxx-03/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/get_container.pass.cpp index 9f45848e..f9b242b 100644 --- a/libcxx/test/libcxx-03/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/get_container.pass.cpp +++ b/libcxx/test/libcxx-03/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/get_container.pass.cpp @@ -17,7 +17,6 @@ #include "test_macros.h" #include "nasty_containers.h" -#include "test_constexpr_container.h" template <class C> TEST_CONSTEXPR_CXX20 bool test(C c) { @@ -29,9 +28,6 @@ TEST_CONSTEXPR_CXX20 bool test(C c) { int main(int, char**) { test(std::vector<int>()); test(nasty_vector<int>()); -#if TEST_STD_VER >= 20 - test(ConstexprFixedCapacityDeque<int, 10>()); - static_assert(test(ConstexprFixedCapacityDeque<int, 10>())); -#endif + return 0; } diff --git a/libcxx/test/libcxx-03/iterators/unwrap_iter.pass.cpp b/libcxx/test/libcxx-03/iterators/unwrap_iter.pass.cpp index 8ef2be2..d93c809 100644 --- a/libcxx/test/libcxx-03/iterators/unwrap_iter.pass.cpp +++ b/libcxx/test/libcxx-03/iterators/unwrap_iter.pass.cpp @@ -51,9 +51,6 @@ TEST_CONSTEXPR_CXX20 bool test() { int main(int, char**) { test(); -#if TEST_STD_VER > 17 - static_assert(test()); -#endif return 0; } diff --git a/libcxx/test/libcxx-03/language.support/support.dynamic/libcpp_deallocate.sh.cpp b/libcxx/test/libcxx-03/language.support/support.dynamic/libcpp_deallocate.sh.cpp index a9fe04f..e782438 100644 --- a/libcxx/test/libcxx-03/language.support/support.dynamic/libcpp_deallocate.sh.cpp +++ b/libcxx/test/libcxx-03/language.support/support.dynamic/libcpp_deallocate.sh.cpp @@ -200,13 +200,6 @@ void test_allocator_and_new_match() { stats.reset(); #elif defined(NO_SIZE) stats.reset(); -# if TEST_STD_VER >= 11 - { - int* x = DoNotOptimize(new int(42)); - delete x; - assert(stats.expect_plain()); - } -# endif stats.reset(); { AlignedType* a = DoNotOptimize(new AlignedType()); diff --git a/libcxx/test/libcxx-03/libcpp_alignof.pass.cpp b/libcxx/test/libcxx-03/libcpp_alignof.pass.cpp index 3ae7f74..8d319d9 100644 --- a/libcxx/test/libcxx-03/libcpp_alignof.pass.cpp +++ b/libcxx/test/libcxx-03/libcpp_alignof.pass.cpp @@ -19,9 +19,6 @@ template <class T> void test() { static_assert(_LIBCPP_ALIGNOF(T) == std::alignment_of<T>::value, ""); static_assert(_LIBCPP_ALIGNOF(T) == TEST_ALIGNOF(T), ""); -#if TEST_STD_VER >= 11 - static_assert(_LIBCPP_ALIGNOF(T) == alignof(T), ""); -#endif #ifdef TEST_COMPILER_CLANG static_assert(_LIBCPP_ALIGNOF(T) == _Alignof(T), ""); #endif diff --git a/libcxx/test/libcxx-03/memory/allocation_guard.pass.cpp b/libcxx/test/libcxx-03/memory/allocation_guard.pass.cpp index 5e71dec..ff6402e 100644 --- a/libcxx/test/libcxx-03/memory/allocation_guard.pass.cpp +++ b/libcxx/test/libcxx-03/memory/allocation_guard.pass.cpp @@ -85,11 +85,7 @@ struct AssignableAllocator { TEST_CONSTEXPR_CXX20 void construct(pointer p, U&& val) { if (stats_ != nullptr) ++stats_->construct_count; -#if TEST_STD_VER > 17 - std::construct_at(std::to_address(p), std::forward<U>(val)); -#else ::new (static_cast<void*>(p)) T(std::forward<U>(val)); -#endif } TEST_CONSTEXPR_CXX14 void destroy(pointer p) { diff --git a/libcxx/test/libcxx-03/memory/swap_allocator.pass.cpp b/libcxx/test/libcxx-03/memory/swap_allocator.pass.cpp index 38dde7a..38fe778 100644 --- a/libcxx/test/libcxx-03/memory/swap_allocator.pass.cpp +++ b/libcxx/test/libcxx-03/memory/swap_allocator.pass.cpp @@ -58,24 +58,5 @@ int main(int, char**) { assert(a2.i == 42); } -#if TEST_STD_VER >= 11 - { - NoexceptSwapAlloc noexcept_alloc; - static_assert(noexcept(std::__swap_allocator(noexcept_alloc, noexcept_alloc)), ""); - } - -#if TEST_STD_VER > 11 - { // From C++14, `__swap_allocator` is unconditionally noexcept. - ThrowingSwapAlloc throwing_alloc; - static_assert(noexcept(std::__swap_allocator(throwing_alloc, throwing_alloc)), ""); - } -#else - { // Until C++14, `__swap_allocator` is only noexcept if the underlying `swap` function is `noexcept`. - ThrowingSwapAlloc throwing_alloc; - static_assert(!noexcept(std::__swap_allocator(throwing_alloc, throwing_alloc)), ""); - } -#endif // TEST_STD_VER > 11 -#endif // TEST_STD_VER >= 11 - return 0; } diff --git a/libcxx/test/libcxx-03/numerics/bit.ops.pass.cpp b/libcxx/test/libcxx-03/numerics/bit.ops.pass.cpp index 0b82f35..1f20811 100644 --- a/libcxx/test/libcxx-03/numerics/bit.ops.pass.cpp +++ b/libcxx/test/libcxx-03/numerics/bit.ops.pass.cpp @@ -29,9 +29,6 @@ TEST_CONSTEXPR_CXX14 bool test() { int main(int, char**) { test(); -#if TEST_STD_VER > 11 - static_assert(test(), ""); -#endif return 0; } diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp index 6bfcb5d..73825ef 100644 --- a/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp +++ b/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp @@ -112,9 +112,6 @@ TEST_CONSTEXPR_CXX20 bool test() { int main(int, char**) { test(); -#if TEST_STD_VER > 17 - static_assert(test()); -#endif return 0; } diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp index d4a0b31..309c84b 100644 --- a/libcxx/test/libcxx-03/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp +++ b/libcxx/test/libcxx-03/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp @@ -15,7 +15,6 @@ #include "test_macros.h" #include "test_allocator.h" -#include "min_allocator.h" template <class S> TEST_CONSTEXPR_CXX20 bool test() { @@ -33,13 +32,6 @@ TEST_CONSTEXPR_CXX20 bool test() { int main(int, char**) { test<std::basic_string<char, std::char_traits<char>, test_allocator<char> > >(); -#if TEST_STD_VER >= 11 - test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>(); -#endif -#if TEST_STD_VER > 17 - static_assert(test<std::basic_string<char, std::char_traits<char>, test_allocator<char>>>()); - static_assert(test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>()); -#endif return 0; } diff --git a/libcxx/test/libcxx-03/strings/c.strings/constexpr_memmove.pass.cpp b/libcxx/test/libcxx-03/strings/c.strings/constexpr_memmove.pass.cpp index d2ca5a2..6c7d194 100644 --- a/libcxx/test/libcxx-03/strings/c.strings/constexpr_memmove.pass.cpp +++ b/libcxx/test/libcxx-03/strings/c.strings/constexpr_memmove.pass.cpp @@ -148,8 +148,6 @@ TEST_CONSTEXPR_CXX14 bool test() { int main(int, char**) { test(); -#if TEST_STD_VER >= 14 - static_assert(test(), ""); -#endif + return 0; } diff --git a/libcxx/test/libcxx-03/type_traits/is_trivially_relocatable.compile.pass.cpp b/libcxx/test/libcxx-03/type_traits/is_trivially_relocatable.compile.pass.cpp index 09049f3..b3880ed 100644 --- a/libcxx/test/libcxx-03/type_traits/is_trivially_relocatable.compile.pass.cpp +++ b/libcxx/test/libcxx-03/type_traits/is_trivially_relocatable.compile.pass.cpp @@ -128,31 +128,11 @@ static_assert(!std::__libcpp_is_trivially_relocatable<std::deque<int, test_alloc static_assert(std::__libcpp_is_trivially_relocatable<std::exception_ptr>::value, ""); #endif -// expected -#if TEST_STD_VER >= 23 -static_assert(std::__libcpp_is_trivially_relocatable<std::expected<int, int> >::value); -static_assert(std::__libcpp_is_trivially_relocatable<std::expected<std::unique_ptr<int>, int>>::value); -static_assert(std::__libcpp_is_trivially_relocatable<std::expected<int, std::unique_ptr<int>>>::value); -static_assert(std::__libcpp_is_trivially_relocatable<std::expected<std::unique_ptr<int>, std::unique_ptr<int>>>::value); - -static_assert(!std::__libcpp_is_trivially_relocatable<std::expected<int, NotTriviallyCopyable>>::value); -static_assert(!std::__libcpp_is_trivially_relocatable<std::expected<NotTriviallyCopyable, int>>::value); -static_assert( - !std::__libcpp_is_trivially_relocatable<std::expected<NotTriviallyCopyable, NotTriviallyCopyable>>::value); -#endif - // locale #ifndef TEST_HAS_NO_LOCALIZATION static_assert(std::__libcpp_is_trivially_relocatable<std::locale>::value, ""); #endif -// optional -#if TEST_STD_VER >= 17 -static_assert(std::__libcpp_is_trivially_relocatable<std::optional<int>>::value, ""); -static_assert(!std::__libcpp_is_trivially_relocatable<std::optional<NotTriviallyCopyable>>::value, ""); -static_assert(std::__libcpp_is_trivially_relocatable<std::optional<std::unique_ptr<int>>>::value, ""); -#endif // TEST_STD_VER >= 17 - // pair static_assert(std::__libcpp_is_trivially_relocatable<std::pair<int, int> >::value, ""); static_assert(!std::__libcpp_is_trivially_relocatable<std::pair<NotTriviallyCopyable, int> >::value, ""); @@ -165,23 +145,6 @@ static_assert(std::__libcpp_is_trivially_relocatable<std::pair<std::unique_ptr<i // shared_ptr static_assert(std::__libcpp_is_trivially_relocatable<std::shared_ptr<NotTriviallyCopyable> >::value, ""); -// tuple -#if TEST_STD_VER >= 11 -static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<> >::value, ""); - -static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<int> >::value, ""); -static_assert(!std::__libcpp_is_trivially_relocatable<std::tuple<NotTriviallyCopyable> >::value, ""); -static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<std::unique_ptr<int> > >::value, ""); - -static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<int, int> >::value, ""); -static_assert(!std::__libcpp_is_trivially_relocatable<std::tuple<NotTriviallyCopyable, int> >::value, ""); -static_assert(!std::__libcpp_is_trivially_relocatable<std::tuple<int, NotTriviallyCopyable> >::value, ""); -static_assert(!std::__libcpp_is_trivially_relocatable<std::tuple<NotTriviallyCopyable, NotTriviallyCopyable> >::value, - ""); -static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<std::unique_ptr<int>, std::unique_ptr<int> > >::value, - ""); -#endif // TEST_STD_VER >= 11 - // unique_ptr struct NotTriviallyRelocatableDeleter { NotTriviallyRelocatableDeleter(const NotTriviallyRelocatableDeleter&); @@ -215,21 +178,6 @@ static_assert(!std::__libcpp_is_trivially_relocatable<std::unique_ptr<int, NotTr static_assert(!std::__libcpp_is_trivially_relocatable<std::unique_ptr<int[], NotTriviallyRelocatablePointer> >::value, ""); -// variant -#if TEST_STD_VER >= 17 -static_assert(std::__libcpp_is_trivially_relocatable<std::variant<int> >::value, ""); -static_assert(!std::__libcpp_is_trivially_relocatable<std::variant<NotTriviallyCopyable> >::value, ""); -static_assert(std::__libcpp_is_trivially_relocatable<std::variant<std::unique_ptr<int> > >::value, ""); - -static_assert(std::__libcpp_is_trivially_relocatable<std::variant<int, int> >::value, ""); -static_assert(!std::__libcpp_is_trivially_relocatable<std::variant<NotTriviallyCopyable, int> >::value, ""); -static_assert(!std::__libcpp_is_trivially_relocatable<std::variant<int, NotTriviallyCopyable> >::value, ""); -static_assert(!std::__libcpp_is_trivially_relocatable<std::variant<NotTriviallyCopyable, NotTriviallyCopyable> >::value, - ""); -static_assert(std::__libcpp_is_trivially_relocatable<std::variant<std::unique_ptr<int>, std::unique_ptr<int> > >::value, - ""); -#endif // TEST_STD_VER >= 17 - // vector static_assert(std::__libcpp_is_trivially_relocatable<std::vector<int> >::value, ""); static_assert(std::__libcpp_is_trivially_relocatable<std::vector<NotTriviallyCopyable> >::value, ""); diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp index 48460d1..a883112 100644 --- a/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp +++ b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp @@ -90,43 +90,6 @@ private: }; -#if TEST_STD_VER >= 11 - -//============================================================================== -// MemFun11 - C++11 reference qualified test member functions. -struct MemFun11 { - typedef void*& R; - typedef MemFun11 C; -#define F(...) \ - R f(__VA_ARGS__) & { return MethodID<R(C::*)(__VA_ARGS__) &>::setUncheckedCall(); } \ - R f(__VA_ARGS__) const & { return MethodID<R(C::*)(__VA_ARGS__) const &>::setUncheckedCall(); } \ - R f(__VA_ARGS__) volatile & { return MethodID<R(C::*)(__VA_ARGS__) volatile &>::setUncheckedCall(); } \ - R f(__VA_ARGS__) const volatile & { return MethodID<R(C::*)(__VA_ARGS__) const volatile &>::setUncheckedCall(); } \ - R f(__VA_ARGS__) && { return MethodID<R(C::*)(__VA_ARGS__) &&>::setUncheckedCall(); } \ - R f(__VA_ARGS__) const && { return MethodID<R(C::*)(__VA_ARGS__) const &&>::setUncheckedCall(); } \ - R f(__VA_ARGS__) volatile && { return MethodID<R(C::*)(__VA_ARGS__) volatile &&>::setUncheckedCall(); } \ - R f(__VA_ARGS__) const volatile && { return MethodID<R(C::*)(__VA_ARGS__) const volatile &&>::setUncheckedCall(); } -# - F() - F(...) - F(ArgType&&) - F(ArgType&&, ...) - F(ArgType&&, ArgType&&) - F(ArgType&&, ArgType&&, ...) - F(ArgType&&, ArgType&&, ArgType&&) - F(ArgType&&, ArgType&&, ArgType&&, ...) -#undef F -public: - MemFun11() {} -private: - MemFun11(MemFun11 const&); - MemFun11& operator=(MemFun11 const&); -}; - -#endif // TEST_STD_VER >= 11 - - - //============================================================================== // TestCase - A test case for a single member function. // ClassType - The type of the class being tested. @@ -167,10 +130,6 @@ private: runTestDispatchIf(NotRValue, tag, dref); runTestDispatchIf(NotRValue, tag, obj_ptr); runTestDispatchIf(NotRValue, tag, der_ptr); -#if TEST_STD_VER >= 11 - runTestDispatchIf(NotRValue, tag, rref); - runTestDispatchIf(NotRValue, tag, drref); -#endif } template <class QT, class Tp> @@ -242,61 +201,6 @@ private: template <class Sig, int Arity, class CV> struct TestCase : public TestCaseImp<MemFun03, Sig, Arity, CV> {}; -#if TEST_STD_VER >= 11 -template <class Sig, int Arity, class CV, bool RValue = false> -struct TestCase11 : public TestCaseImp<MemFun11, Sig, Arity, CV, RValue, true> {}; - -template <class Type> -struct ReferenceWrapper { - using type = Type; - Type* ptr; - - static void fun(Type&) noexcept; - static void fun(Type&&) = delete; - - template <class Type2, - class = typename std::enable_if<!std::__is_same_uncvref<Type2, ReferenceWrapper>::value>::type> - constexpr ReferenceWrapper(Type2&& t) noexcept : ptr(&t) {} - - constexpr Type& get() const noexcept { return *ptr; } - constexpr operator Type&() const noexcept { return *ptr; } - - template <class... _ArgTypes> - constexpr std::__invoke_result_t<Type&, _ArgTypes...> operator()(_ArgTypes&&... __args) const { - return std::__invoke(get(), std::forward<_ArgTypes>(__args)...); - } -}; - -template <class Tp> -struct DerivedFromRefWrap : public ReferenceWrapper<Tp> { - constexpr DerivedFromRefWrap(Tp& tp) : ReferenceWrapper<Tp>(tp) {} -}; - -TEST_CONSTEXPR_CXX14 bool test_derived_from_ref_wrap() { - int x = 42; - ReferenceWrapper<int> r(x); - DerivedFromRefWrap<int> d(x); - auto get_fn = &ReferenceWrapper<int>::get; - auto& ret = std::__invoke(get_fn, r); - assert(&ret == &x); - auto& ret2 = std::__invoke(get_fn, d); - assert(&ret2 == &x); - - return true; -} - -TEST_CONSTEXPR_CXX20 bool test_reference_wrapper_reference_wrapper() { - int x = 42; - auto get_fn = &std::reference_wrapper<int>::get; - std::reference_wrapper<int> r(x); - std::reference_wrapper<std::reference_wrapper<int>> r2(r); - auto& ret3 = std::__invoke(get_fn, r2); - assert(&ret3 == &x); - - return true; -} -#endif - int main(int, char**) { typedef void*& R; typedef ArgType A; @@ -333,73 +237,5 @@ int main(int, char**) { TestCase<R(A&, A&, A&, ...) volatile, 3, Q_Volatile>::run(); TestCase<R(A&, A&, A&, ...) const volatile, 3, Q_CV>::run(); -#if TEST_STD_VER >= 11 - TestCase11<R() &, 0, Q_None>::run(); - TestCase11<R() const &, 0, Q_Const>::run(); - TestCase11<R() volatile &, 0, Q_Volatile>::run(); - TestCase11<R() const volatile &, 0, Q_CV>::run(); - TestCase11<R(...) &, 0, Q_None>::run(); - TestCase11<R(...) const &, 0, Q_Const>::run(); - TestCase11<R(...) volatile &, 0, Q_Volatile>::run(); - TestCase11<R(...) const volatile &, 0, Q_CV>::run(); - TestCase11<R(A&&) &, 1, Q_None>::run(); - TestCase11<R(A&&) const &, 1, Q_Const>::run(); - TestCase11<R(A&&) volatile &, 1, Q_Volatile>::run(); - TestCase11<R(A&&) const volatile &, 1, Q_CV>::run(); - TestCase11<R(A&&, ...) &, 1, Q_None>::run(); - TestCase11<R(A&&, ...) const &, 1, Q_Const>::run(); - TestCase11<R(A&&, ...) volatile &, 1, Q_Volatile>::run(); - TestCase11<R(A&&, ...) const volatile &, 1, Q_CV>::run(); - TestCase11<R(A&&, A&&) &, 2, Q_None>::run(); - TestCase11<R(A&&, A&&) const &, 2, Q_Const>::run(); - TestCase11<R(A&&, A&&) volatile &, 2, Q_Volatile>::run(); - TestCase11<R(A&&, A&&) const volatile &, 2, Q_CV>::run(); - TestCase11<R(A&&, A&&, ...) &, 2, Q_None>::run(); - TestCase11<R(A&&, A&&, ...) const &, 2, Q_Const>::run(); - TestCase11<R(A&&, A&&, ...) volatile &, 2, Q_Volatile>::run(); - TestCase11<R(A&&, A&&, ...) const volatile &, 2, Q_CV>::run(); - TestCase11<R() &&, 0, Q_None, /* RValue */ true>::run(); - TestCase11<R() const &&, 0, Q_Const, /* RValue */ true>::run(); - TestCase11<R() volatile &&, 0, Q_Volatile, /* RValue */ true>::run(); - TestCase11<R() const volatile &&, 0, Q_CV, /* RValue */ true>::run(); - TestCase11<R(...) &&, 0, Q_None, /* RValue */ true>::run(); - TestCase11<R(...) const &&, 0, Q_Const, /* RValue */ true>::run(); - TestCase11<R(...) volatile &&, 0, Q_Volatile, /* RValue */ true>::run(); - TestCase11<R(...) const volatile &&, 0, Q_CV, /* RValue */ true>::run(); - TestCase11<R(A&&) &&, 1, Q_None, /* RValue */ true>::run(); - TestCase11<R(A&&) const &&, 1, Q_Const, /* RValue */ true>::run(); - TestCase11<R(A&&) volatile &&, 1, Q_Volatile, /* RValue */ true>::run(); - TestCase11<R(A&&) const volatile &&, 1, Q_CV, /* RValue */ true>::run(); - TestCase11<R(A&&, ...) &&, 1, Q_None, /* RValue */ true>::run(); - TestCase11<R(A&&, ...) const &&, 1, Q_Const, /* RValue */ true>::run(); - TestCase11<R(A&&, ...) volatile &&, 1, Q_Volatile, /* RValue */ true>::run(); - TestCase11<R(A&&, ...) const volatile &&, 1, Q_CV, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&) &&, 2, Q_None, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&) const &&, 2, Q_Const, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&) volatile &&, 2, Q_Volatile, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&) const volatile &&, 2, Q_CV, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, ...) &&, 2, Q_None, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, ...) const &&, 2, Q_Const, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, ...) volatile &&, 2, Q_Volatile, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, ...) const volatile &&, 2, Q_CV, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, A&&) &&, 3, Q_None, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, A&&) const &&, 3, Q_Const, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, A&&) volatile &&, 3, Q_Volatile, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, A&&) const volatile &&, 3, Q_CV, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, A&&, ...) &&, 3, Q_None, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, A&&, ...) const &&, 3, Q_Const, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, A&&, ...) volatile &&, 3, Q_Volatile, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, A&&, ...) const volatile &&, 3, Q_CV, /* RValue */ true>::run(); - - test_derived_from_ref_wrap(); - test_reference_wrapper_reference_wrapper(); -#if TEST_STD_VER > 11 - static_assert(test_derived_from_ref_wrap(), ""); -#endif -#if TEST_STD_VER > 17 - static_assert(test_reference_wrapper_reference_wrapper(), ""); -#endif -#endif // TEST_STD_VER >= 11 - return 0; } diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp index 0df5929..3a8d141 100644 --- a/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp +++ b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp @@ -85,10 +85,6 @@ private: runTestDispatch<E>(M, dref2, &dref2.object.object); runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object); runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object); -#if TEST_STD_VER >= 11 - runTestPropCVDispatch<E>(M, rref, &(rref.get().object)); - runTestPropCVDispatch<E>(M, drref, &(drref.get().object)); -#endif runTestNoPropDispatch<E>(M, dref, &dref.object.object); } { @@ -100,10 +96,6 @@ private: runTestDispatch<E>(M, dref2, &dref2.object.object); runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object); runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object); -#if TEST_STD_VER >= 11 - runTestPropCVDispatch<E>(M, rref, &(rref.get().object)); - runTestPropCVDispatch<E>(M, drref, &(drref.get().object)); -#endif runTestNoPropDispatch<E>(M, dref, &dref.object.object); } { @@ -115,10 +107,6 @@ private: runTestDispatch<E>(M, dref2, &dref2.object.object); runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object); runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object); -#if TEST_STD_VER >= 11 - runTestPropCVDispatch<E>(M, rref, &(rref.get().object)); - runTestPropCVDispatch<E>(M, drref, &(drref.get().object)); -#endif runTestNoPropDispatch<E>(M, dref, &dref.object.object); } { @@ -130,10 +118,6 @@ private: runTestDispatch<E>(M, dref2, &dref2.object.object); runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object); runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object); -#if TEST_STD_VER >= 11 - runTestPropCVDispatch<E>(M, rref, &(rref.get().object)); - runTestPropCVDispatch<E>(M, drref, &(drref.get().object)); -#endif runTestNoPropDispatch<E>(M, dref, &dref.object.object); } } @@ -144,12 +128,6 @@ private: runTest<Expect const&> (M, C_<T const&>(obj), expect); runTest<Expect volatile&> (M, C_<T volatile&>(obj), expect); runTest<Expect const volatile&>(M, C_<T const volatile&>(obj), expect); -#if TEST_STD_VER >= 11 - runTest<Expect&&> (M, C_<T&&>(obj), expect); - runTest<Expect const&&> (M, C_<T const&&>(obj), expect); - runTest<Expect volatile&&> (M, C_<T volatile&&>(obj), expect); - runTest<Expect const volatile&&>(M, C_<T const volatile&&>(obj), expect); -#endif } template <class Expect, class Fn, class T> @@ -166,12 +144,6 @@ private: runTest<Expect&>(M, C_<T const&>(obj), expect); runTest<Expect&>(M, C_<T volatile&>(obj), expect); runTest<Expect&>(M, C_<T const volatile&>(obj), expect); -#if TEST_STD_VER >= 11 - runTest<Expect&>(M, C_<T&&>(obj), expect); - runTest<Expect&>(M, C_<T const&&>(obj), expect); - runTest<Expect&>(M, C_<T volatile&&>(obj), expect); - runTest<Expect&>(M, C_<T const volatile&&>(obj), expect); -#endif } template <class Expect, class Fn, class T> @@ -184,11 +156,7 @@ private: } template <class Expect, class Fn, class T> -#if TEST_STD_VER >= 11 - void runTest(Fn M, T&& obj, ObjectType* expect) { -#else void runTest(Fn M, T& obj, ObjectType* expect ) { -#endif { static_assert((std::is_same< decltype(std::__invoke(M, std::forward<T>(obj))), Expect diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_7.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_7.pass.cpp index fb789fa..ba1c655 100644 --- a/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_7.pass.cpp +++ b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_7.pass.cpp @@ -115,49 +115,6 @@ private: }; -#if TEST_STD_VER >= 11 - -//============================================================================== -// freeFunction11 - A C++11 free function. -template <class ...Args> -void*& freeFunction11(Args&&...) { - return FunctionPtrID<void*&(Args&&...), freeFunction11>::setUncheckedCall(); -} - -template <class ...Args> -void*& freeFunction11(Args&&...,...) { - return FunctionPtrID<void*&(Args&&...,...), freeFunction11>::setUncheckedCall(); -} - -//============================================================================== -// Functor11 - C++11 reference qualified test member functions. -struct Functor11 { - typedef void*& R; - typedef Functor11 C; - -#define F(CV) \ - template <class ...Args> \ - R operator()(Args&&...) CV { return MethodID<R(C::*)(Args&&...) CV>::setUncheckedCall(); } -# - F(&) - F(const &) - F(volatile &) - F(const volatile &) - F(&&) - F(const &&) - F(volatile &&) - F(const volatile &&) -#undef F -public: - Functor11() {} -private: - Functor11(Functor11 const&); - Functor11& operator=(Functor11 const&); -}; - -#endif // TEST_STD_VER >= 11 - - //============================================================================== // TestCaseFunctorImp - A test case for an operator() class method. // ClassType - The type of the call object. @@ -207,19 +164,9 @@ public: //============================================================================== // runTest Helpers //============================================================================== -#if TEST_STD_VER >= 11 -template <class Sig, int Arity, class ArgCaster> -void runFunctionTestCase11() { - TestCaseFreeFunction<Sig, freeFunction11, Arity, ArgCaster>(); -} -#endif - template <class Sig, int Arity, class ArgCaster> void runFunctionTestCase() { TestCaseFreeFunction<Sig, freeFunction03, Arity, ArgCaster>(); -#if TEST_STD_VER >= 11 - runFunctionTestCase11<Sig, Arity, ArgCaster>(); -#endif } template <class Sig, int Arity, class ObjCaster, class ArgCaster> @@ -232,14 +179,6 @@ void runFunctorTestCase() { TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster>::run(); } -#if TEST_STD_VER >= 11 -// runTestCase - Run a test case for C++11 class functor types -template <class Sig, int Arity, class ObjCaster, class ArgCaster = LValueCaster> -void runFunctorTestCase11() { - TestCaseFunctorImp<Functor11, Sig, Arity, ObjCaster, ArgCaster>::run(); -} -#endif - // runTestCase - Run a test case for both function and functor types. template <class Sig, int Arity, class ArgCaster> void runTestCase() { @@ -265,11 +204,6 @@ int main(int, char**) { runFunctionTestCase<R(A&, A&, ...), 2, LValueCaster >(); runFunctionTestCase<R(A&, A&, A&, ...), 3, LValueCaster >(); -#if TEST_STD_VER >= 11 - runFunctionTestCase11<R(A&&), 1, MoveCaster >(); - runFunctionTestCase11<R(A&&, ...), 1, MoveCaster >(); -#endif - runFunctorTestCase<R(), 0, LValueCaster >(); runFunctorTestCase<R() const, 0, ConstCaster >(); runFunctorTestCase<R() volatile, 0, VolatileCaster >(); @@ -302,27 +236,5 @@ int main(int, char**) { runFunctorTestCase<R(CA&, CA&, CA&) const volatile, 3, CVCaster, CC>(); } -#if TEST_STD_VER >= 11 - runFunctorTestCase11<R() &, 0, LValueCaster >(); - runFunctorTestCase11<R() const &, 0, ConstCaster >(); - runFunctorTestCase11<R() volatile &, 0, VolatileCaster >(); - runFunctorTestCase11<R() const volatile &, 0, CVCaster >(); - runFunctorTestCase11<R() &&, 0, MoveCaster >(); - runFunctorTestCase11<R() const &&, 0, MoveConstCaster >(); - runFunctorTestCase11<R() volatile &&, 0, MoveVolatileCaster >(); - runFunctorTestCase11<R() const volatile &&, 0, MoveCVCaster >(); - { - typedef MoveCaster MC; - runFunctorTestCase11<R(A&&) &, 1, LValueCaster, MC>(); - runFunctorTestCase11<R(A&&) const &, 1, ConstCaster, MC>(); - runFunctorTestCase11<R(A&&) volatile &, 1, VolatileCaster, MC>(); - runFunctorTestCase11<R(A&&) const volatile &, 1, CVCaster, MC>(); - runFunctorTestCase11<R(A&&) &&, 1, MoveCaster, MC>(); - runFunctorTestCase11<R(A&&) const &&, 1, MoveConstCaster, MC>(); - runFunctorTestCase11<R(A&&) volatile &&, 1, MoveVolatileCaster, MC>(); - runFunctorTestCase11<R(A&&) const volatile &&, 1, MoveCVCaster, MC>(); - } -#endif - return 0; } diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke.pass.cpp index e534553..bfcea06 100644 --- a/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke.pass.cpp +++ b/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke.pass.cpp @@ -23,24 +23,12 @@ struct Type { Array<char, 1>::type& f1(); Array<char, 2>::type& f2() const; -#if TEST_STD_VER >= 11 - Array<char, 1>::type& g1() &; - Array<char, 2>::type& g2() const &; - Array<char, 3>::type& g3() &&; - Array<char, 4>::type& g4() const &&; -#endif }; int main(int, char**) { static_assert(sizeof(std::__invoke(&Type::f1, std::declval<Type >())) == 1, ""); static_assert(sizeof(std::__invoke(&Type::f2, std::declval<Type const >())) == 2, ""); -#if TEST_STD_VER >= 11 - static_assert(sizeof(std::__invoke(&Type::g1, std::declval<Type &>())) == 1, ""); - static_assert(sizeof(std::__invoke(&Type::g2, std::declval<Type const &>())) == 2, ""); - static_assert(sizeof(std::__invoke(&Type::g3, std::declval<Type &&>())) == 3, ""); - static_assert(sizeof(std::__invoke(&Type::g4, std::declval<Type const&&>())) == 4, ""); -#endif return 0; } diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke_helpers.h b/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke_helpers.h index f6f418b..bebb9f4 100644 --- a/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke_helpers.h +++ b/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke_helpers.h @@ -52,13 +52,7 @@ struct Caster { struct apply { typedef typename std::remove_reference<T>::type RawType; typedef typename QualTag::template apply<RawType>::type CVType; -#if TEST_STD_VER >= 11 - typedef typename std::conditional<RValue, - CVType&&, CVType& - >::type type; -#else typedef CVType& type; -#endif }; template <class T> @@ -165,21 +159,10 @@ struct DerefPropType { template <class Up> explicit DerefPropType(Up const& val) : object(val) {} -#if TEST_STD_VER < 11 To& operator*() { return object; } To const& operator*() const { return object; } To volatile& operator*() volatile { return object; } To const volatile& operator*() const volatile { return object; } -#else - To& operator*() & { return object; } - To const& operator*() const & { return object; } - To volatile& operator*() volatile & { return object; } - To const volatile& operator*() const volatile & { return object; } - To&& operator*() && { return static_cast<To &&>(object); } - To const&& operator*() const && { return static_cast<To const&&>(object); } - To volatile&& operator*() volatile && { return static_cast<To volatile&&>(object); } - To const volatile&& operator*() const volatile && { return static_cast<To const volatile&&>(object); } -#endif }; //============================================================================== diff --git a/libcxx/test/libcxx-03/utilities/is_pointer_in_range.pass.cpp b/libcxx/test/libcxx-03/utilities/is_pointer_in_range.pass.cpp index 6c60147..bb33ee4 100644 --- a/libcxx/test/libcxx-03/utilities/is_pointer_in_range.pass.cpp +++ b/libcxx/test/libcxx-03/utilities/is_pointer_in_range.pass.cpp @@ -18,20 +18,6 @@ TEST_CONSTEXPR_CXX14 void test_cv_quals() { assert(!std::__is_pointer_in_range(&i, &i, &i)); assert(std::__is_pointer_in_range(&i, &i + 1, &i)); assert(!std::__is_pointer_in_range(&i, &i + 1, &j)); - -#if TEST_STD_VER >= 20 - { - T* arr1 = new int[4]{1, 2, 3, 4}; - U* arr2 = new int[4]{5, 6, 7, 8}; - - assert(!std::__is_pointer_in_range(arr1, arr1 + 4, arr2)); - assert(std::__is_pointer_in_range(arr1, arr1 + 4, arr1 + 3)); - assert(!std::__is_pointer_in_range(arr1, arr1, arr1 + 3)); - - delete[] arr1; - delete[] arr2; - } -#endif } TEST_CONSTEXPR_CXX14 bool test() { @@ -48,9 +34,6 @@ TEST_CONSTEXPR_CXX14 bool test() { int main(int, char**) { test(); -#if TEST_STD_VER >= 14 - static_assert(test(), ""); -#endif return 0; } diff --git a/libcxx/test/libcxx-03/utilities/is_valid_range.pass.cpp b/libcxx/test/libcxx-03/utilities/is_valid_range.pass.cpp index 9ad1e89..ef645d4 100644 --- a/libcxx/test/libcxx-03/utilities/is_valid_range.pass.cpp +++ b/libcxx/test/libcxx-03/utilities/is_valid_range.pass.cpp @@ -39,14 +39,6 @@ TEST_CONSTEXPR_CXX14 void check_type() { assert(!std::__is_valid_range(static_cast<TQualified*>(&arr[1]), static_cast<TQualified*>(&arr[0]))); assert(!std::__is_valid_range(static_cast<TQualified*>(&arr[2]), static_cast<TQualified*>(&arr[0]))); } - -#if TEST_STD_VER >= 20 - { - T* arr = new int[4]{1, 2, 3, 4}; - assert(std::__is_valid_range(static_cast<TQualified*>(arr), static_cast<TQualified*>(arr + 4))); - delete[] arr; - } -#endif } TEST_CONSTEXPR_CXX14 bool test() { @@ -60,9 +52,6 @@ TEST_CONSTEXPR_CXX14 bool test() { int main(int, char**) { test(); -#if TEST_STD_VER >= 14 - static_assert(test(), ""); -#endif return 0; } diff --git a/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address.pass.cpp b/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address.pass.cpp index 60ef98a..f6df5db 100644 --- a/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address.pass.cpp +++ b/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address.pass.cpp @@ -152,8 +152,6 @@ TEST_CONSTEXPR_CXX14 bool test() { int main(int, char**) { test(); -#if TEST_STD_VER >= 14 - static_assert(test(), ""); -#endif + return 0; } diff --git a/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp b/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp index 5eed12d..3b7527d 100644 --- a/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp +++ b/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp @@ -44,12 +44,6 @@ int main(int, char**) { test_container_iterators(std::array<int, 3>()); test_container_iterators(std::vector<int>(3)); test_container_iterators(std::string("abc")); -#if TEST_STD_VER >= 17 - test_container_iterators(std::string_view("abc")); -#endif -#if TEST_STD_VER >= 20 - test_container_iterators(std::span<const char>("abc")); -#endif test_valarray_iterators(); return 0; diff --git a/libcxx/test/libcxx-03/utilities/meta/is_referenceable.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/meta/is_referenceable.compile.pass.cpp index f39d1a5..a079bbe 100644 --- a/libcxx/test/libcxx-03/utilities/meta/is_referenceable.compile.pass.cpp +++ b/libcxx/test/libcxx-03/utilities/meta/is_referenceable.compile.pass.cpp @@ -33,10 +33,6 @@ static_assert((std::__libcpp_is_referenceable<Foo>::value), ""); static_assert((std::__libcpp_is_referenceable<const Foo>::value), ""); static_assert((std::__libcpp_is_referenceable<Foo&>::value), ""); static_assert((std::__libcpp_is_referenceable<const Foo&>::value), ""); -#if TEST_STD_VER >= 11 -static_assert((std::__libcpp_is_referenceable<Foo&&>::value), ""); -static_assert((std::__libcpp_is_referenceable<const Foo&&>::value), ""); -#endif static_assert((std::__libcpp_is_referenceable<int __attribute__((__vector_size__(8)))>::value), ""); static_assert((std::__libcpp_is_referenceable<const int __attribute__((__vector_size__(8)))>::value), ""); @@ -45,146 +41,42 @@ static_assert((std::__libcpp_is_referenceable<const float __attribute__((__vecto // Functions without cv-qualifiers are referenceable static_assert((std::__libcpp_is_referenceable<void()>::value), ""); -#if TEST_STD_VER >= 11 -static_assert((!std::__libcpp_is_referenceable<void() const>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void() &>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void() const&>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void() &&>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void() const&&>::value), ""); -#endif static_assert((std::__libcpp_is_referenceable<void(int)>::value), ""); -#if TEST_STD_VER >= 11 -static_assert((!std::__libcpp_is_referenceable<void(int) const>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int) &>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int) const&>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int) &&>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int) const&&>::value), ""); -#endif static_assert((std::__libcpp_is_referenceable<void(int, float)>::value), ""); -#if TEST_STD_VER >= 11 -static_assert((!std::__libcpp_is_referenceable<void(int, float) const>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, float) &>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, float) const&>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, float) &&>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, float) const&&>::value), ""); -#endif static_assert((std::__libcpp_is_referenceable<void(int, float, Foo&)>::value), ""); -#if TEST_STD_VER >= 11 -static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&) const>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&) &>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&) const&>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&) &&>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&) const&&>::value), ""); -#endif static_assert((std::__libcpp_is_referenceable<void(...)>::value), ""); -#if TEST_STD_VER >= 11 -static_assert((!std::__libcpp_is_referenceable<void(...) const>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(...) &>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(...) const&>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(...) &&>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(...) const&&>::value), ""); -#endif static_assert((std::__libcpp_is_referenceable<void(int, ...)>::value), ""); -#if TEST_STD_VER >= 11 -static_assert((!std::__libcpp_is_referenceable<void(int, ...) const>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, ...) &>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, ...) const&>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, ...) &&>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, ...) const&&>::value), ""); -#endif static_assert((std::__libcpp_is_referenceable<void(int, float, ...)>::value), ""); -#if TEST_STD_VER >= 11 -static_assert((!std::__libcpp_is_referenceable<void(int, float, ...) const>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, float, ...) &>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, float, ...) const&>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, float, ...) &&>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, float, ...) const&&>::value), ""); -#endif static_assert((std::__libcpp_is_referenceable<void(int, float, Foo&, ...)>::value), ""); -#if TEST_STD_VER >= 11 -static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&, ...) const>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&, ...) &>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&, ...) const&>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&, ...) &&>::value), ""); -static_assert((!std::__libcpp_is_referenceable<void(int, float, Foo&, ...) const&&>::value), ""); -#endif // member functions with or without cv-qualifiers are referenceable static_assert((std::__libcpp_is_referenceable<void (Foo::*)()>::value), ""); static_assert((std::__libcpp_is_referenceable<void (Foo::*)() const>::value), ""); -#if TEST_STD_VER >= 11 -static_assert((std::__libcpp_is_referenceable<void (Foo::*)() &>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)() const&>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)() &&>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)() const&&>::value), ""); -#endif static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int)>::value), ""); static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int) const>::value), ""); -#if TEST_STD_VER >= 11 -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int) &>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int) const&>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int) &&>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int) const&&>::value), ""); -#endif static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float)>::value), ""); static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float) const>::value), ""); -#if TEST_STD_VER >= 11 -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float) &>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float) const&>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float) &&>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float) const&&>::value), ""); -#endif static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&)>::value), ""); static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&) const>::value), ""); -#if TEST_STD_VER >= 11 -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&) &>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&) const&>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&) &&>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&) const&&>::value), ""); -#endif static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...)>::value), ""); static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...) const>::value), ""); -#if TEST_STD_VER >= 11 -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...) &>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...) const&>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...) &&>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(...) const&&>::value), ""); -#endif static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...)>::value), ""); static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...) const>::value), ""); -#if TEST_STD_VER >= 11 -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...) &>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...) const&>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...) &&>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, ...) const&&>::value), ""); -#endif static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...)>::value), ""); static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...) const>::value), ""); -#if TEST_STD_VER >= 11 -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...) &>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...) const&>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...) &&>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, ...) const&&>::value), ""); -#endif static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...)>::value), ""); static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...) const>::value), ""); -#if TEST_STD_VER >= 11 -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...) &>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...) const&>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...) &&>::value), ""); -static_assert((std::__libcpp_is_referenceable<void (Foo::*)(int, float, Foo&, ...) const&&>::value), ""); -#endif diff --git a/libcxx/test/libcxx-03/utilities/no_destroy.pass.cpp b/libcxx/test/libcxx-03/utilities/no_destroy.pass.cpp index 561654d..c79d208 100644 --- a/libcxx/test/libcxx-03/utilities/no_destroy.pass.cpp +++ b/libcxx/test/libcxx-03/utilities/no_destroy.pass.cpp @@ -11,11 +11,6 @@ #include "test_macros.h" -#if TEST_STD_VER > 17 -// Test constexpr-constructibility. -constinit std::__no_destroy<int> nd_int_const(std::__uninitialized_tag{}); -#endif - struct DestroyLast { ~DestroyLast() { assert(*ptr == 5); } diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.non_trivial_copy_move.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.non_trivial_copy_move.pass.cpp index 1f5dae1..d961884 100644 --- a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.non_trivial_copy_move.pass.cpp +++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.non_trivial_copy_move.pass.cpp @@ -31,49 +31,8 @@ template <class T> struct HasNonTrivialABI : std::integral_constant<bool, !std::is_trivially_destructible<T>::value || (std::is_copy_constructible<T>::value && !std::is_trivially_copy_constructible<T>::value) -#if TEST_STD_VER >= 11 - || (std::is_move_constructible<T>::value && !std::is_trivially_move_constructible<T>::value) -#endif > {}; -#if TEST_STD_VER >= 11 -struct NonTrivialDtor { - NonTrivialDtor(NonTrivialDtor const&) = default; - ~NonTrivialDtor(); -}; -NonTrivialDtor::~NonTrivialDtor() {} -static_assert(HasNonTrivialABI<NonTrivialDtor>::value, ""); - -struct NonTrivialCopy { - NonTrivialCopy(NonTrivialCopy const&); -}; -NonTrivialCopy::NonTrivialCopy(NonTrivialCopy const&) {} -static_assert(HasNonTrivialABI<NonTrivialCopy>::value, ""); - -struct NonTrivialMove { - NonTrivialMove(NonTrivialMove const&) = default; - NonTrivialMove(NonTrivialMove&&); -}; -NonTrivialMove::NonTrivialMove(NonTrivialMove&&) {} -static_assert(HasNonTrivialABI<NonTrivialMove>::value, ""); - -struct DeletedCopy { - DeletedCopy(DeletedCopy const&) = delete; - DeletedCopy(DeletedCopy&&) = default; -}; -static_assert(!HasNonTrivialABI<DeletedCopy>::value, ""); - -struct TrivialMove { - TrivialMove(TrivialMove &&) = default; -}; -static_assert(!HasNonTrivialABI<TrivialMove>::value, ""); - -struct Trivial { - Trivial(Trivial const&) = default; -}; -static_assert(!HasNonTrivialABI<Trivial>::value, ""); -#endif - void test_trivial() { @@ -82,62 +41,6 @@ void test_trivial() static_assert(std::is_copy_constructible<P>::value, ""); static_assert(HasNonTrivialABI<P>::value, ""); } -#if TEST_STD_VER >= 11 - { - typedef std::pair<int, short> P; - static_assert(std::is_move_constructible<P>::value, ""); - static_assert(HasNonTrivialABI<P>::value, ""); - } - { - using P = std::pair<NonTrivialDtor, int>; - static_assert(!std::is_trivially_destructible<P>::value, ""); - static_assert(std::is_copy_constructible<P>::value, ""); - static_assert(!std::is_trivially_copy_constructible<P>::value, ""); - static_assert(std::is_move_constructible<P>::value, ""); - static_assert(!std::is_trivially_move_constructible<P>::value, ""); - static_assert(HasNonTrivialABI<P>::value, ""); - } - { - using P = std::pair<NonTrivialCopy, int>; - static_assert(std::is_copy_constructible<P>::value, ""); - static_assert(!std::is_trivially_copy_constructible<P>::value, ""); - static_assert(std::is_move_constructible<P>::value, ""); - static_assert(!std::is_trivially_move_constructible<P>::value, ""); - static_assert(HasNonTrivialABI<P>::value, ""); - } - { - using P = std::pair<NonTrivialMove, int>; - static_assert(std::is_copy_constructible<P>::value, ""); - static_assert(!std::is_trivially_copy_constructible<P>::value, ""); - static_assert(std::is_move_constructible<P>::value, ""); - static_assert(!std::is_trivially_move_constructible<P>::value, ""); - static_assert(HasNonTrivialABI<P>::value, ""); - } - { - using P = std::pair<DeletedCopy, int>; - static_assert(!std::is_copy_constructible<P>::value, ""); - static_assert(!std::is_trivially_copy_constructible<P>::value, ""); - static_assert(std::is_move_constructible<P>::value, ""); - static_assert(!std::is_trivially_move_constructible<P>::value, ""); - static_assert(HasNonTrivialABI<P>::value, ""); - } - { - using P = std::pair<Trivial, int>; - static_assert(std::is_copy_constructible<P>::value, ""); - static_assert(!std::is_trivially_copy_constructible<P>::value, ""); - static_assert(std::is_move_constructible<P>::value, ""); - static_assert(!std::is_trivially_move_constructible<P>::value, ""); - static_assert(HasNonTrivialABI<P>::value, ""); - } - { - using P = std::pair<TrivialMove, int>; - static_assert(!std::is_copy_constructible<P>::value, ""); - static_assert(!std::is_trivially_copy_constructible<P>::value, ""); - static_assert(std::is_move_constructible<P>::value, ""); - static_assert(!std::is_trivially_move_constructible<P>::value, ""); - static_assert(HasNonTrivialABI<P>::value, ""); - } -#endif } void test_layout() { diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivial_copy_move.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivial_copy_move.pass.cpp index 3ec60c0..1dafb10 100644 --- a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivial_copy_move.pass.cpp +++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivial_copy_move.pass.cpp @@ -28,49 +28,8 @@ template <class T> struct HasTrivialABI : std::integral_constant<bool, std::is_trivially_destructible<T>::value && (!std::is_copy_constructible<T>::value || std::is_trivially_copy_constructible<T>::value) -#if TEST_STD_VER >= 11 - && (!std::is_move_constructible<T>::value || std::is_trivially_move_constructible<T>::value) -#endif > {}; -#if TEST_STD_VER >= 11 -struct NonTrivialDtor { - NonTrivialDtor(NonTrivialDtor const&) = default; - ~NonTrivialDtor(); -}; -NonTrivialDtor::~NonTrivialDtor() {} -static_assert(!HasTrivialABI<NonTrivialDtor>::value, ""); - -struct NonTrivialCopy { - NonTrivialCopy(NonTrivialCopy const&); -}; -NonTrivialCopy::NonTrivialCopy(NonTrivialCopy const&) {} -static_assert(!HasTrivialABI<NonTrivialCopy>::value, ""); - -struct NonTrivialMove { - NonTrivialMove(NonTrivialMove const&) = default; - NonTrivialMove(NonTrivialMove&&); -}; -NonTrivialMove::NonTrivialMove(NonTrivialMove&&) {} -static_assert(!HasTrivialABI<NonTrivialMove>::value, ""); - -struct DeletedCopy { - DeletedCopy(DeletedCopy const&) = delete; - DeletedCopy(DeletedCopy&&) = default; -}; -static_assert(HasTrivialABI<DeletedCopy>::value, ""); - -struct TrivialMove { - TrivialMove(TrivialMove &&) = default; -}; -static_assert(HasTrivialABI<TrivialMove>::value, ""); - -struct Trivial { - Trivial(Trivial const&) = default; -}; -static_assert(HasTrivialABI<Trivial>::value, ""); -#endif - struct TrivialNoAssignment { int arr[4]; TrivialNoAssignment& operator=(const TrivialNoAssignment&) = delete; @@ -90,78 +49,14 @@ void test_trivial() static_assert(std::is_copy_constructible<P>::value, ""); static_assert(HasTrivialABI<P>::value, ""); } -#if TEST_STD_VER >= 11 - { - typedef std::pair<int, short> P; - static_assert(std::is_move_constructible<P>::value, ""); - static_assert(HasTrivialABI<P>::value, ""); - } - { - using P = std::pair<NonTrivialDtor, int>; - static_assert(!std::is_trivially_destructible<P>::value, ""); - static_assert(std::is_copy_constructible<P>::value, ""); - static_assert(!std::is_trivially_copy_constructible<P>::value, ""); - static_assert(std::is_move_constructible<P>::value, ""); - static_assert(!std::is_trivially_move_constructible<P>::value, ""); - static_assert(!HasTrivialABI<P>::value, ""); - } - { - using P = std::pair<NonTrivialCopy, int>; - static_assert(std::is_copy_constructible<P>::value, ""); - static_assert(!std::is_trivially_copy_constructible<P>::value, ""); - static_assert(std::is_move_constructible<P>::value, ""); - static_assert(!std::is_trivially_move_constructible<P>::value, ""); - static_assert(!HasTrivialABI<P>::value, ""); - } - { - using P = std::pair<NonTrivialMove, int>; - static_assert(std::is_copy_constructible<P>::value, ""); - static_assert(std::is_trivially_copy_constructible<P>::value, ""); - static_assert(std::is_move_constructible<P>::value, ""); - static_assert(!std::is_trivially_move_constructible<P>::value, ""); - static_assert(!HasTrivialABI<P>::value, ""); - } - { - using P = std::pair<DeletedCopy, int>; - static_assert(!std::is_copy_constructible<P>::value, ""); - static_assert(!std::is_trivially_copy_constructible<P>::value, ""); - static_assert(std::is_move_constructible<P>::value, ""); - static_assert(std::is_trivially_move_constructible<P>::value, ""); - static_assert(HasTrivialABI<P>::value, ""); - } - { - using P = std::pair<Trivial, int>; - static_assert(std::is_copy_constructible<P>::value, ""); - static_assert(std::is_trivially_copy_constructible<P>::value, ""); - static_assert(std::is_move_constructible<P>::value, ""); - static_assert(std::is_trivially_move_constructible<P>::value, ""); - static_assert(HasTrivialABI<P>::value, ""); - } - { - using P = std::pair<TrivialMove, int>; - static_assert(!std::is_copy_constructible<P>::value, ""); - static_assert(!std::is_trivially_copy_constructible<P>::value, ""); - static_assert(std::is_move_constructible<P>::value, ""); - static_assert(std::is_trivially_move_constructible<P>::value, ""); - static_assert(HasTrivialABI<P>::value, ""); - } -#endif { using P = std::pair<TrivialNoAssignment, int>; static_assert(std::is_trivially_copy_constructible<P>::value, ""); static_assert(std::is_trivially_move_constructible<P>::value, ""); -#if TEST_STD_VER >= 11 // This is https://llvm.org/PR90605 - static_assert(!std::is_trivially_copy_assignable<P>::value, ""); - static_assert(!std::is_trivially_move_assignable<P>::value, ""); -#endif // TEST_STD_VER >= 11 static_assert(std::is_trivially_destructible<P>::value, ""); } { using P = std::pair<TrivialNoConstruction, int>; -#if TEST_STD_VER >= 11 - static_assert(!std::is_trivially_copy_constructible<P>::value, ""); - static_assert(!std::is_trivially_move_constructible<P>::value, ""); -#endif // TEST_STD_VER >= 11 static_assert(!std::is_trivially_copy_assignable<P>::value, ""); static_assert(!std::is_trivially_move_assignable<P>::value, ""); static_assert(std::is_trivially_destructible<P>::value, ""); diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivially_copyable.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivially_copyable.compile.pass.cpp index 1132b3e..7bd1adc 100644 --- a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivially_copyable.compile.pass.cpp +++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivially_copyable.compile.pass.cpp @@ -52,13 +52,8 @@ static_assert(!std::is_trivially_copyable<std::pair<int, char> >::value, ""); static_assert(!std::is_trivially_copyable<std::pair<char, int> >::value, ""); static_assert(!std::is_trivially_copyable<std::pair<std::pair<char, char>, int> >::value, ""); static_assert(!std::is_trivially_copyable<std::pair<trivially_copyable, int> >::value, ""); -#if TEST_STD_VER == 03 // Known ABI difference static_assert(!std::is_trivially_copyable<std::pair<trivially_copyable_no_copy_assignment, int> >::value, ""); static_assert(!std::is_trivially_copyable<std::pair<trivially_copyable_no_move_assignment, int> >::value, ""); -#else -static_assert(std::is_trivially_copyable<std::pair<trivially_copyable_no_copy_assignment, int> >::value, ""); -static_assert(std::is_trivially_copyable<std::pair<trivially_copyable_no_move_assignment, int> >::value, ""); -#endif static_assert(!std::is_trivially_copyable<std::pair<trivially_copyable_no_construction, int> >::value, ""); static_assert(std::is_trivially_copy_constructible<std::pair<int, int> >::value, ""); diff --git a/libcxx/test/libcxx/algorithms/alg.modifying.operations/copy_move_unwrap_reverse.pass.cpp b/libcxx/test/libcxx/algorithms/alg.modifying.operations/copy_move_unwrap_reverse.pass.cpp index 2a85e7b..2244462 100644 --- a/libcxx/test/libcxx/algorithms/alg.modifying.operations/copy_move_unwrap_reverse.pass.cpp +++ b/libcxx/test/libcxx/algorithms/alg.modifying.operations/copy_move_unwrap_reverse.pass.cpp @@ -19,6 +19,7 @@ #include <cstdint> #include <iterator> #include <type_traits> +#include <utility> #include "test_iterators.h" diff --git a/libcxx/test/libcxx/assertions/semantics/assertion_semantic_incorrect_value.sh.cpp b/libcxx/test/libcxx/assertions/semantics/assertion_semantic_incorrect_value.sh.cpp new file mode 100644 index 0000000..d7c1e26 --- /dev/null +++ b/libcxx/test/libcxx/assertions/semantics/assertion_semantic_incorrect_value.sh.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// This test verifies that setting the assertion semantic to a value that's not part of the predefined constants +// triggers a compile-time error. + +// Modules build produces a different error ("Could not build module 'std'"). +// UNSUPPORTED: clang-modules-build +// UNSUPPORTED: c++03, libcpp-has-no-experimental-hardening-observe-semantic +// REQUIRES: verify-support + +// RUN: %{verify} -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=42 +// `hardening-dependent` cannot be set as the semantic (it's only an indicator to use hardening-related logic to pick +// the final semantic). +// RUN: %{verify} -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT +// Make sure that common cases of misuse produce readable errors. We deliberately disallow setting the assertion +// semantic as if it were a boolean flag. +// RUN: %{verify} -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=0 +// RUN: %{verify} -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=1 +// RUN: %{verify} -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC + +#include <cassert> + +// expected-error@*:* {{_LIBCPP_ASSERTION_SEMANTIC must be set to one of the following values: _LIBCPP_ASSERTION_SEMANTIC_IGNORE, _LIBCPP_ASSERTION_SEMANTIC_OBSERVE, _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE, _LIBCPP_ASSERTION_SEMANTIC_ENFORCE}} diff --git a/libcxx/test/libcxx/assertions/semantics/override_with_enforce_semantic.pass.cpp b/libcxx/test/libcxx/assertions/semantics/override_with_enforce_semantic.pass.cpp new file mode 100644 index 0000000..056864e --- /dev/null +++ b/libcxx/test/libcxx/assertions/semantics/override_with_enforce_semantic.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// This test ensures that we can override the assertion semantic used by any checked hardening mode with `enforce` on +// a per-TU basis (this is valid for the `debug` mode as well, though a no-op). + +// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support. +// REQUIRES: has-unix-headers +// UNSUPPORTED: c++03, no-localization +// UNSUPPORTED: libcpp-hardening-mode=none, libcpp-has-no-experimental-hardening-observe-semantic +// The ability to set a custom abort message is required to compare the assertion message. +// XFAIL: availability-verbose_abort-missing +// ADDITIONAL_COMPILE_FLAGS: -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_ENFORCE + +#include <cassert> +#include "check_assertion.h" + +int main(int, char**) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire"); + TEST_LIBCPP_ASSERT_FAILURE([] { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Should fire and log a message"); }(), + "Should fire and log a message"); + + return 0; +} diff --git a/libcxx/test/libcxx/assertions/semantics/override_with_ignore_semantic.pass.cpp b/libcxx/test/libcxx/assertions/semantics/override_with_ignore_semantic.pass.cpp new file mode 100644 index 0000000..b8c9028 --- /dev/null +++ b/libcxx/test/libcxx/assertions/semantics/override_with_ignore_semantic.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// This test ensures that we can override the assertion semantic used by any hardening mode with `ignore` on a per-TU +// basis (this is valid for the `none` mode as well, though a no-op). + +// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support. +// REQUIRES: has-unix-headers +// UNSUPPORTED: c++03, no-localization +// UNSUPPORTED: libcpp-has-no-experimental-hardening-observe-semantic +// ADDITIONAL_COMPILE_FLAGS: -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_IGNORE + +#include <cassert> +#include "check_assertion.h" + +int main(int, char**) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Also should not fire"); + + return 0; +} diff --git a/libcxx/test/libcxx/assertions/semantics/override_with_observe_semantic.pass.cpp b/libcxx/test/libcxx/assertions/semantics/override_with_observe_semantic.pass.cpp new file mode 100644 index 0000000..a14c44f --- /dev/null +++ b/libcxx/test/libcxx/assertions/semantics/override_with_observe_semantic.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// This test ensures that we can override the assertion semantic used by any checked hardening mode with `observe` on +// a per-TU basis. + +// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support. +// REQUIRES: has-unix-headers +// UNSUPPORTED: c++03, no-localization +// UNSUPPORTED: libcpp-hardening-mode=none, libcpp-has-no-experimental-hardening-observe-semantic +// ADDITIONAL_COMPILE_FLAGS: -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_OBSERVE + +#include <cassert> +#include "check_assertion.h" + +int main(int, char**) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Also should not fire"); + // TODO(hardening): check that a message is logged. + + return 0; +} diff --git a/libcxx/test/libcxx/assertions/semantics/override_with_quick_enforce_semantic.pass.cpp b/libcxx/test/libcxx/assertions/semantics/override_with_quick_enforce_semantic.pass.cpp new file mode 100644 index 0000000..be5038c --- /dev/null +++ b/libcxx/test/libcxx/assertions/semantics/override_with_quick_enforce_semantic.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// This test ensures that we can override the assertion semantic used by any checked hardening mode with `quick-enforce` +// on a per-TU basis (this is valid for the `fast` and `extensive` modes as well, though a no-op). + +// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support. +// REQUIRES: has-unix-headers +// UNSUPPORTED: c++03, no-localization +// UNSUPPORTED: libcpp-hardening-mode=none, libcpp-has-no-experimental-hardening-observe-semantic +// ADDITIONAL_COMPILE_FLAGS: -U_LIBCPP_ASSERTION_SEMANTIC -D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE + +#include <cassert> +#include "check_assertion.h" + +int main(int, char**) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire"); + TEST_LIBCPP_ASSERT_FAILURE( + [] { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Should fire without logging a message"); }(), + "The message should not matter"); + + return 0; +} diff --git a/libcxx/test/libcxx/atomics/atomics.syn/wait.issue_85107.pass.cpp b/libcxx/test/libcxx/atomics/atomics.syn/wait.issue_85107.pass.cpp index f606e93..ed2a8b0 100644 --- a/libcxx/test/libcxx/atomics/atomics.syn/wait.issue_85107.pass.cpp +++ b/libcxx/test/libcxx/atomics/atomics.syn/wait.issue_85107.pass.cpp @@ -41,7 +41,11 @@ int main(int, char**) { // This would hang forever if the bug is present, but the test will fail in a bounded amount of // time due to the timeout above. +#if _LIBCPP_AVAILABILITY_HAS_NEW_SYNC + std::__atomic_wait_native<sizeof(std::__cxx_atomic_contention_t)>(&ct, &old_val); +#else std::__libcpp_atomic_wait(&ct, old_val); +#endif done = true; timeout_thread.join(); diff --git a/libcxx/test/libcxx/containers/views/mdspan/extents/assert.obs.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.obs.pass.cpp index c473879..e32c0a9 100644 --- a/libcxx/test/libcxx/containers/views/mdspan/extents/assert.obs.pass.cpp +++ b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.obs.pass.cpp @@ -35,28 +35,28 @@ int main(int, char**) { // mismatch of static extent { std::extents<int> e; - TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(0); }()), "extents access: index must be less than rank"); - TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(0); }()), "extents access: index must be less than rank"); + TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.extent(0); }()), "extents access: index must be less than rank"); + TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.static_extent(0); }()), "extents access: index must be less than rank"); } { std::extents<int, D> e; - TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(2); }()), "extents access: index must be less than rank"); - TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(2); }()), "extents access: index must be less than rank"); + TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.extent(2); }()), "extents access: index must be less than rank"); + TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.static_extent(2); }()), "extents access: index must be less than rank"); } { std::extents<int, 5> e; - TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(2); }()), "extents access: index must be less than rank"); - TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(2); }()), "extents access: index must be less than rank"); + TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.extent(2); }()), "extents access: index must be less than rank"); + TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.static_extent(2); }()), "extents access: index must be less than rank"); } { std::extents<int, D, 5> e; - TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(2); }()), "extents access: index must be less than rank"); - TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(2); }()), "extents access: index must be less than rank"); + TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.extent(2); }()), "extents access: index must be less than rank"); + TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.static_extent(2); }()), "extents access: index must be less than rank"); } { std::extents<int, 1, 2, 3, 4, 5, 6, 7, 8> e; - TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(9); }()), "extents access: index must be less than rank"); - TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(9); }()), "extents access: index must be less than rank"); + TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.extent(9); }()), "extents access: index must be less than rank"); + TEST_LIBCPP_ASSERT_FAILURE(([=] { (void)e.static_extent(9); }()), "extents access: index must be less than rank"); } // check that static_extent works in constant expression with assertions enabled diff --git a/libcxx/test/libcxx/containers/views/mdspan/nodiscard.verify.cpp b/libcxx/test/libcxx/containers/views/mdspan/nodiscard.verify.cpp new file mode 100644 index 0000000..71f53f8 --- /dev/null +++ b/libcxx/test/libcxx/containers/views/mdspan/nodiscard.verify.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++23 + +// <span> + +// Check that functions are marked [[nodiscard]] + +#include <array> +#include <mdspan> +#include <span> + +void test() { + // mdspan<> + + std::array<int, 4> data; + std::mdspan<int, std::extents<std::size_t, 2, 2>> mdsp{data.data(), 2, 2}; + + mdsp[0, 1]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::array arr{0, 1}; + mdsp[arr]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::span sp{arr}; + mdsp[sp]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + mdsp.rank(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + mdsp.rank_dynamic(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + mdsp.static_extent(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + mdsp.extent(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + mdsp.extents(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + mdsp.data_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + mdsp.mapping(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + mdsp.accessor(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + mdsp.is_always_unique(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + mdsp.is_always_exhaustive(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + mdsp.is_always_strided(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + mdsp.is_unique(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + mdsp.is_exhaustive(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + mdsp.is_strided(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + mdsp.stride(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + // Helpers + + std::extents<int, 1, 2> ex; + ex.rank(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ex.rank_dynamic(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ex.static_extent(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ex.extent(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::dextents<int, 2> dex; + dex.rank(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + dex.rank_dynamic(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + dex.static_extent(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + dex.extent(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +} diff --git a/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp new file mode 100644 index 0000000..6666805 --- /dev/null +++ b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++20 + +// <span> + +// Check that functions are marked [[nodiscard]] + +#include <span> + +#include "test_macros.h" + +void test() { + { // Test with a static extent + std::span<int, 0> sp; + + sp.first<0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.last<0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.first(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.last(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.subspan<0, 0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.subspan(0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.size_bytes(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#if TEST_STD_VER >= 26 + sp.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif + sp.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::as_bytes(sp); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::as_writable_bytes(sp); + } + { // Test with a dynamic extent + std::span<int> sp; + + sp.first<0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.last<0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.first(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.last(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.subspan<0, 0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.subspan(0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.size_bytes(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#if TEST_STD_VER >= 26 + sp.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif + sp.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::as_bytes(sp); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::as_writable_bytes(sp); + } +} diff --git a/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp index 25a2f80..8e49807 100644 --- a/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp @@ -11,13 +11,70 @@ // check that <array> functions are marked [[nodiscard]] #include <array> +#include <utility> -void array_test() { - std::array<int, 1> array; - array.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#include <test_macros.h> + +template <std::size_t N> +void test_members() { + std::array<int, N> a; + const std::array<int, N> ca{}; + + a.begin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.begin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.end(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.end(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.rbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.rbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.rend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.rend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.cbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.cbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.cend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.cend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.crbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.crbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.crend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.crend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + + a.size(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.max_size(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.empty(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + + a[0]; // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca[0]; // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.at(0); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.at(0); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + + a.front(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.front(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.back(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.back(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + + a.data(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.data(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} +} + +template <typename ArrT> +void test_get() { + std::array<int, 94> a{}; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::get<0>(a); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::get<0>(std::move(a)); +} + +#if TEST_STD_VER >= 20 +void test_to_array() { + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_array("zmt"); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_array({94, 82, 49}); } +#endif -void empty_array_test() { - std::array<int, 0> array; - array.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +void test() { + test_members<0>(); + test_members<82>(); } diff --git a/libcxx/test/libcxx/diagnostics/deque.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/deque.nodiscard.verify.cpp index e8dda09..a9adb175 100644 --- a/libcxx/test/libcxx/diagnostics/deque.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/deque.nodiscard.verify.cpp @@ -13,6 +13,32 @@ #include <deque> void test() { - std::deque<int> deque; - deque.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::deque<int> d; + const std::deque<int> cd; + + d.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cd.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + d.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cd.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + d.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cd.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + d.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cd.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cd.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cd.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cd.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cd.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + d.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + d.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + d.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + d[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cd[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + d.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cd.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + d.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cd.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + d.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cd.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } diff --git a/libcxx/test/libcxx/diagnostics/flat_map.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/flat_map.nodiscard.verify.cpp index 79b943b7..7d75083 100644 --- a/libcxx/test/libcxx/diagnostics/flat_map.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/flat_map.nodiscard.verify.cpp @@ -6,15 +6,107 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// REQUIRES: std-at-least-c++23 // <flat_map> -// [[nodiscard]] bool empty() const noexcept; +// Check that functions are marked [[nodiscard]] #include <flat_map> +#include <utility> -void f() { - std::flat_map<int, int> c; - c.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +template <typename T> +struct TransparentKey { + T t; + + constexpr explicit operator T() const { return t; } +}; + +struct TransparentCompare { + using is_transparent = void; // This makes the comparator transparent + + template <typename T> + constexpr bool operator()(const T& t, const TransparentKey<T>& transparent) const { + return t < transparent.t; + } + + template <typename T> + constexpr bool operator()(const TransparentKey<T>& transparent, const T& t) const { + return transparent.t < t; + } + + template <typename T> + constexpr bool operator()(const T& t1, const T& t2) const { + return t1 < t2; + } +}; + +void test() { + std::flat_map<int, int, TransparentCompare> fm; + const std::flat_map<int, int, TransparentCompare> cfm{}; + + fm.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fm.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fm.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fm.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fm.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fm.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fm.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + int key = 0; + TransparentKey<int> tkey; + + std::flat_map<int, int> nfm; + nfm[key]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fm[std::move(key)]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fm[std::move(tkey)]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fm.at(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.at(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fm.at(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.at(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::move(fm).extract(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fm.key_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fm.value_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fm.keys(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fm.values(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fm.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fm.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fm.count(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fm.count(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fm.contains(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.contains(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fm.contains(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.contains(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fm.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fm.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fm.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fm.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fm.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fm.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfm.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } diff --git a/libcxx/test/libcxx/diagnostics/flat_set.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/flat_set.nodiscard.verify.cpp index 161fe53..89d6045 100644 --- a/libcxx/test/libcxx/diagnostics/flat_set.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/flat_set.nodiscard.verify.cpp @@ -6,15 +6,93 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// REQUIRES: std-at-least-c++23 // <flat_set> -// [[nodiscard]] bool empty() const noexcept; +// Check that functions are marked [[nodiscard]] #include <flat_set> +#include <utility> -void f() { - std::flat_set<int> c; - c.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +template <typename T> +struct TransparentKey { + T t; + + constexpr explicit operator T() const { return t; } +}; + +struct TransparentCompare { + using is_transparent = void; // This makes the comparator transparent + + template <typename T> + constexpr bool operator()(const T& t, const TransparentKey<T>& transparent) const { + return t < transparent.t; + } + + template <typename T> + constexpr bool operator()(const TransparentKey<T>& transparent, const T& t) const { + return transparent.t < t; + } + + template <typename T> + constexpr bool operator()(const T& t1, const T& t2) const { + return t1 < t2; + } +}; + +void test() { + std::flat_set<int, TransparentCompare> fs; + const std::flat_set<int, TransparentCompare> cfs; + + fs.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfs.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fs.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfs.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fs.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfs.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fs.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfs.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfs.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfs.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfs.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfs.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fs.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fs.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fs.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::move(fs).extract(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fs.key_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fs.value_comp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + int key = 0; + TransparentKey<int> tkey; + + fs.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfs.find(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fs.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfs.find(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fs.count(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fs.count(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fs.contains(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fs.contains(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fs.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfs.lower_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fs.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfs.lower_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fs.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfs.upper_bound(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fs.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfs.upper_bound(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fs.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfs.equal_range(key); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fs.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfs.equal_range(tkey); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } diff --git a/libcxx/test/libcxx/diagnostics/forward_list.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/forward_list.nodiscard.verify.cpp index 7594a1d..671c7f7 100644 --- a/libcxx/test/libcxx/diagnostics/forward_list.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/forward_list.nodiscard.verify.cpp @@ -13,6 +13,27 @@ #include <forward_list> void test() { - std::forward_list<int> forward_list; - forward_list.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::forward_list<int> fl; + const std::forward_list<int> cfl; + + fl.get_allocator(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fl.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfl.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fl.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfl.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fl.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfl.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fl.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfl.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fl.before_begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfl.before_begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fl.cbefore_begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfl.cbefore_begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fl.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + fl.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + fl.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cfl.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } diff --git a/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp index 4307976..521870f 100644 --- a/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp @@ -6,15 +6,63 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: c++03 // check that <functional> functions are marked [[nodiscard]] +#include <cstddef> #include <functional> #include "test_macros.h" void test() { int i = 0; - std::identity()(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + // Function wrappers + +#if !defined(TEST_HAS_NO_RTTI) + std::function<void(int)> f; + const std::function<void(int)> cf; + + f.target_type(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + f.target<void(int)>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cf.target<void(int)>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif + struct ZMT { + void member_function() {}; + }; + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::mem_fn(&ZMT::member_function); + + // Identity + +#if TEST_STD_VER >= 20 + std::identity{}(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif + + // Partial function application + +#if TEST_STD_VER >= 23 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::bind_back([](int a) { return a; }, 94); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::bind_front([](int a) { return a; }, 94); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::bind([](int a) { return a; }, 94); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::bind<float>([](int a) { return a; }, 94); + + // Reference wrappers + + std::reference_wrapper<int> rw{i}; + rw.get(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::ref(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::cref(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + // Hash specializations + + std::hash<std::nullptr_t> hash; + hash(nullptr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } diff --git a/libcxx/test/libcxx/diagnostics/list.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/list.nodiscard.verify.cpp index f19224a7..bfce9b8 100644 --- a/libcxx/test/libcxx/diagnostics/list.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/list.nodiscard.verify.cpp @@ -13,6 +13,33 @@ #include <list> void test() { - std::list<int> list; - list.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::list<int> l; + const std::list<int> cl; + + l.get_allocator(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + l.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + l.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + l.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + l.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cl.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + l.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cl.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + l.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cl.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + l.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cl.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + l.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cl.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + l.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cl.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + l.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cl.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + l.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cl.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + l.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cl.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + l.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cl.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } diff --git a/libcxx/test/libcxx/diagnostics/queue.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/queue.nodiscard.verify.cpp index 77d3367..da1f9ff 100644 --- a/libcxx/test/libcxx/diagnostics/queue.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/queue.nodiscard.verify.cpp @@ -12,12 +12,24 @@ #include <queue> -void test_queue() { - std::queue<int> queue; - queue.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} -} +void test() { + { + std::queue<int> q; + const std::queue<int> cq{}; + + q.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + q.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + q.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cq.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + q.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cq.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + + { + std::priority_queue<int> pq; -void test_priority_queue() { - std::priority_queue<int> priority_queue; - priority_queue.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + pq.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + pq.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + pq.top(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } } diff --git a/libcxx/test/libcxx/diagnostics/stack.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/stack.nodiscard.verify.cpp index 861852a..a0a5b3c 100644 --- a/libcxx/test/libcxx/diagnostics/stack.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/stack.nodiscard.verify.cpp @@ -13,6 +13,11 @@ #include <stack> void test() { - std::stack<int> stack; - stack.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stack<int> st; + const std::stack<int> cst; + + st.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + st.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + st.top(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cst.top(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } diff --git a/libcxx/test/libcxx/diagnostics/string.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/string.nodiscard.verify.cpp index d421eaf..0ff92ca 100644 --- a/libcxx/test/libcxx/diagnostics/string.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/string.nodiscard.verify.cpp @@ -11,13 +11,199 @@ // check that <string> functions are marked [[nodiscard]] #include <string> +#include <string_view> #include "test_macros.h" +std::string prval(); + void test() { - std::string string; - string.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::string str; + const std::string cstr; + std::string_view sv; + + str[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cstr[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cstr.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + str.c_str(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cstr.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + str.substr(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + prval().substr(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + str.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cstr.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cstr.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + str.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cstr.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cstr.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + str.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cstr.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cstr.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + str.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + str.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + str.capacity(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.length(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.get_allocator(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + str.find(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find("", 0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + str.rfind(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.rfind(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.rfind(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.rfind(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.rfind("", 0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + // clang-format off + str.find_first_of(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find_first_of(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find_first_of(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find_first_of(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find_first_of("", 0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + str.find_last_of(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find_last_of(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find_last_of(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find_last_of(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find_last_of("", 0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + str.find_first_not_of(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find_first_not_of(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find_first_not_of(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find_first_not_of(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find_first_not_of("", 0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + str.find_last_not_of(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find_last_not_of(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find_last_not_of(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find_last_not_of(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.find_last_not_of("", 0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + str.compare(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.compare(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.compare(0, 0, sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.compare(0, 0, sv, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.compare(0, 0, str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.compare(0, 0, str, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.compare(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.compare(0, 0, ""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.compare(0, 0, "", 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // clang-format on + +#if TEST_STD_VER >= 20 + str.starts_with(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.starts_with(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.starts_with(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + str.ends_with(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.ends_with(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.ends_with(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif + +#if TEST_STD_VER >= 23 + str.contains(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.contains(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.contains(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif + #if TEST_STD_VER >= 26 - string.subview(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + str.subview(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif +} + +void test_nonmembers() { + // Numeric conversions + + std::string str; + + std::stoi(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stol(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stoll(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stoull(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::stof(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stod(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stold(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::to_string(94); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_string(82U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_string(94L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_string(82UL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_string(94LL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_string(82ULL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_string(94.0F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_string(82.0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_string(94.0L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + +#if !defined(TEST_HAS_NO_WIDE_CHARACTERS) + + std::wstring wstr; + + std::stoi(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stol(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stoll(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stoull(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::stof(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stod(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stold(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::to_wstring(94); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_wstring(82U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_wstring(94L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_wstring(82UL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_wstring(94LL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_wstring(82ULL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_wstring(94.0F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_wstring(82.0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_wstring(94.0L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + +#endif + + // std::hash<> + + std::hash<std::string> hash; + + hash(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + +#if TEST_STD_VER >= 14 + // string literals + + using namespace std::string_literals; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ""s; // const char* +# if !defined(TEST_HAS_NO_WIDE_CHARACTERS) + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + L""s; // const wchar_t* +# endif +# if !defined(TEST_HAS_NO_CHAR8_T) + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + u8""s; // const char8_t* +# endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + u""s; // const char16_t* + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + U""s; // const char32_t* #endif } diff --git a/libcxx/test/libcxx/diagnostics/string_view.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/string_view.nodiscard.verify.cpp index e5b2258..89e4a5b 100644 --- a/libcxx/test/libcxx/diagnostics/string_view.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/string_view.nodiscard.verify.cpp @@ -12,12 +12,140 @@ #include <string_view> +#include "type_algorithms.h" #include "test_macros.h" -void test() { - std::string_view string_view; - string_view.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +void test_members() { + std::string_view sv; + + sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + sv.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.length(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + sv.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + sv[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + sv.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + sv.substr(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} #if TEST_STD_VER >= 26 - string_view.subview(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.subview(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.compare(sv); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.compare(0, 0, sv); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.compare(0, 0, sv, 0, 0); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.compare(""); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.compare(0, 0, ""); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.compare(0, 0, "", 0); + + sv.find(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find("", 0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find("", 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + sv.rfind(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.rfind(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.rfind("", 0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.rfind("", 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find_first_of(sv); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find_first_of(' '); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find_first_of("", 0, 0); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find_first_of("", 0); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find_last_of(sv); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find_last_of(' '); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find_last_of("", 0, 0); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find_last_of("", 0); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find_first_not_of(sv); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find_first_not_of(' '); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find_first_not_of("", 0, 0); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find_first_not_of("", 0); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find_last_not_of(sv); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find_last_not_of(' '); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find_last_not_of("", 0, 0); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.find_last_not_of("", 0); + +#if TEST_STD_VER >= 20 + sv.starts_with(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.starts_with(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.starts_with(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + sv.ends_with(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.ends_with(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.ends_with(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif + +#if TEST_STD_VER >= 23 + sv.contains(sv); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.contains(' '); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.contains(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif +} + +void test_nonmembers() { + // std::hash<> + + std::hash<std::string_view> hash; + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + hash(std::string_view{}); + +#if TEST_STD_VER >= 14 + // string_view literals + + using namespace std::string_view_literals; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ""sv; // const char* +# if !defined(TEST_HAS_NO_WIDE_CHARACTERS) + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + L""sv; // const wchar_t* +# endif +# if !defined(TEST_HAS_NO_CHAR8_T) + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + u8""sv; // const char8_t* +# endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + u""sv; // const char16_t* + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + U""sv; // const char32_t* #endif } diff --git a/libcxx/test/libcxx/diagnostics/syserr/nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/syserr/nodiscard.verify.cpp new file mode 100644 index 0000000..26565a1 --- /dev/null +++ b/libcxx/test/libcxx/diagnostics/syserr/nodiscard.verify.cpp @@ -0,0 +1,108 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// Check that functions are marked [[nodiscard]] + +#include <stdexcept> +#include <system_error> + +void test() { + { // <stdexcept> + std::logic_error le("logic error"); + le.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::runtime_error re("runtime error"); + re.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::domain_error de("domain error"); + de.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::invalid_argument ia("invalid argument"); + ia.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::length_error lerr("length error"); + lerr.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::out_of_range oor("out of range"); + oor.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::range_error rerr("range error"); + rerr.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::overflow_error oferr("overflow error"); + oferr.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::underflow_error uferr("underflow error"); + uferr.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + { // <system_error> + { + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::generic_category(); + + const std::error_category& ec = std::generic_category(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ec.name(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ec.default_error_condition(94); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ec.equivalent(94, ec.default_error_condition(82)); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ec.equivalent(std::error_code(49, ec), 94); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ec.message(82); + } + { + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::system_category(); + + const std::error_category& ec = std::system_category(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ec.name(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ec.default_error_condition(94); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ec.equivalent(94, ec.default_error_condition(82)); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ec.equivalent(std::error_code(49, ec), 94); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ec.message(82); + } + { + std::error_code ec; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ec.value(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ec.category(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ec.default_error_condition(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ec.message(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::make_error_code(std::errc::invalid_argument); + } + { + std::error_condition ec; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ec.value(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ec.category(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ec.message(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::make_error_condition(std::errc::invalid_argument); + } + } +} diff --git a/libcxx/test/libcxx/diagnostics/utility.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/utility.nodiscard.verify.cpp index 524be96..2f5b3ba 100644 --- a/libcxx/test/libcxx/diagnostics/utility.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/utility.nodiscard.verify.cpp @@ -10,8 +10,6 @@ // check that <utility> functions are marked [[nodiscard]] -// clang-format off - #include <utility> #include "test_macros.h" @@ -19,15 +17,33 @@ void test() { int i = 0; - std::forward<int>(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::forward<int>(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::move(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::move_if_noexcept(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::forward<int>(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::forward<int>(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::move(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::move_if_noexcept(i); #if TEST_STD_VER >= 17 std::as_const(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} #endif +#if TEST_STD_VER >= 20 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::cmp_equal(94, 82); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::cmp_not_equal(94, 82); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::cmp_less(94, 82); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::cmp_greater(94, 82); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::cmp_less_equal(94, 82); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::cmp_greater_equal(94, 82); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::in_range<long>(49); +#endif + #if TEST_STD_VER >= 23 enum E { Apple, Orange } e = Apple; std::to_underlying(e); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} diff --git a/libcxx/test/libcxx/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp b/libcxx/test/libcxx/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp index 30e7b66..283adbc 100644 --- a/libcxx/test/libcxx/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp +++ b/libcxx/test/libcxx/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp @@ -19,4 +19,4 @@ std::basic_filebuf<char, std::char_traits<wchar_t> > f; // expected-error-re@*:* {{static assertion failed{{.*}}traits_type::char_type must be the same type as CharT}} -// expected-error@*:* 11 {{only virtual member functions can be marked 'override'}} +// expected-error@*:* 10 {{only virtual member functions can be marked 'override'}} diff --git a/libcxx/test/libcxx/input.output/file.streams/fstreams/traits_mismatch.verify.cpp b/libcxx/test/libcxx/input.output/file.streams/fstreams/traits_mismatch.verify.cpp index daafb36..ba6f3c3 100644 --- a/libcxx/test/libcxx/input.output/file.streams/fstreams/traits_mismatch.verify.cpp +++ b/libcxx/test/libcxx/input.output/file.streams/fstreams/traits_mismatch.verify.cpp @@ -21,7 +21,7 @@ std::basic_fstream<char, std::char_traits<wchar_t> > f; // expected-error-re@*:* {{static assertion failed{{.*}}traits_type::char_type must be the same type as CharT}} // expected-error-re@*:* {{static assertion failed{{.*}}traits_type::char_type must be the same type as CharT}} -// expected-error@*:* 13 {{only virtual member functions can be marked 'override'}} +// expected-error@*:* 12 {{only virtual member functions can be marked 'override'}} // FIXME: As of commit r324062 Clang incorrectly generates a diagnostic about mismatching // exception specifications for types which are already invalid for one reason or another. diff --git a/libcxx/test/libcxx/language.support/nodiscard.verify.cpp b/libcxx/test/libcxx/language.support/nodiscard.verify.cpp new file mode 100644 index 0000000..eeadd9f --- /dev/null +++ b/libcxx/test/libcxx/language.support/nodiscard.verify.cpp @@ -0,0 +1,129 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION + +// Check that functions are marked [[nodiscard]] + +#include <compare> +#include <coroutine> +#include <exception> +#include <initializer_list> + +#include "test_macros.h" + +void test() { +#if TEST_STD_VER >= 20 + { // <compare> + int x = 94; + int y = 82; + auto oRes = x <=> y; + + std::is_eq(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::is_neq(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::is_lt(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::is_lteq(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::is_gt(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::is_gteq(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } +#endif + +#if TEST_STD_VER >= 20 + { // <coroutine> + struct EmptyPromise { + } promise; + + { + std::coroutine_handle<void> cr{}; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + cr.address(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::coroutine_handle<void>::from_address(&promise); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + cr.done(); + + std::hash<std::coroutine_handle<void>> hash; + hash(cr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + { + std::coroutine_handle<EmptyPromise> cr; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::coroutine_handle<EmptyPromise>::from_promise(promise); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + cr.address(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::coroutine_handle<EmptyPromise>::from_address(&promise); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + cr.done(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + cr.promise(); + } + { + std::coroutine_handle<std::noop_coroutine_promise> cr = std::noop_coroutine(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + cr.done(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + cr.promise(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + cr.address(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::noop_coroutine(); + } + } +#endif + + { // <exception> + { + std::bad_exception bex; + + bex.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + { + std::exception ex; + + ex.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + { + std::nested_exception nex; + + nex.nested_ptr(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + +#if TEST_STD_VER <= 14 + std::get_unexpected(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif + + std::get_terminate(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + +#if _LIBCPP_STD_VER <= 17 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::uncaught_exception(); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::uncaught_exceptions(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::current_exception(); + } + +#if TEST_STD_VER >= 11 + { // <initializer_list> + std::initializer_list<int> il{94, 82, 49}; + + il.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + il.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + il.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } +#endif +} diff --git a/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp b/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp index 4bb42cb..282d49d 100644 --- a/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp +++ b/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp @@ -21,6 +21,8 @@ // GCC doesn't support the aligned-allocation flags. // XFAIL: gcc +// ADDITIONAL_COMPILE_FLAGS: -I %{libcxx-dir}/src -Wno-macro-redefined + // RUN: %{build} -faligned-allocation -fsized-deallocation // RUN: %{run} // RUN: %{build} -faligned-allocation -fno-sized-deallocation -DNO_SIZE @@ -36,10 +38,7 @@ #include "test_macros.h" -TEST_DIAGNOSTIC_PUSH -TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header") -#include <__memory/aligned_alloc.h> -TEST_DIAGNOSTIC_POP +#include "include/aligned_alloc.h" struct alloc_stats { alloc_stats() { reset(); } diff --git a/libcxx/test/libcxx/memory/allocation_guard.pass.cpp b/libcxx/test/libcxx/memory/allocation_guard.pass.cpp index 493ebf0..a7c9397 100644 --- a/libcxx/test/libcxx/memory/allocation_guard.pass.cpp +++ b/libcxx/test/libcxx/memory/allocation_guard.pass.cpp @@ -17,6 +17,8 @@ #include <__memory/allocation_guard.h> #include <cassert> +#include <climits> +#include <memory> #include <type_traits> #include <utility> diff --git a/libcxx/test/libcxx/memory/uninitialized_allocator_copy.pass.cpp b/libcxx/test/libcxx/memory/uninitialized_allocator_copy.pass.cpp index 679ee86..1d127f9 100644 --- a/libcxx/test/libcxx/memory/uninitialized_allocator_copy.pass.cpp +++ b/libcxx/test/libcxx/memory/uninitialized_allocator_copy.pass.cpp @@ -11,6 +11,7 @@ // ensure that __uninitialized_allocator_copy calls the proper construct and destruct functions #include <algorithm> +#include <cassert> #include <iterator> #include <memory> diff --git a/libcxx/test/libcxx/numerics/clamp_to_integral.pass.cpp b/libcxx/test/libcxx/numerics/clamp_to_integral.pass.cpp index aed78f9..937593c 100644 --- a/libcxx/test/libcxx/numerics/clamp_to_integral.pass.cpp +++ b/libcxx/test/libcxx/numerics/clamp_to_integral.pass.cpp @@ -16,6 +16,7 @@ #include <cassert> #include <cmath> #include <limits> +#include <type_traits> template <class IntT> void test() { diff --git a/libcxx/test/libcxx/strings/basic.string/nonnull.verify.cpp b/libcxx/test/libcxx/strings/basic.string/nonnull.verify.cpp index f428c49..c9df9f0 100644 --- a/libcxx/test/libcxx/strings/basic.string/nonnull.verify.cpp +++ b/libcxx/test/libcxx/strings/basic.string/nonnull.verify.cpp @@ -13,6 +13,8 @@ // Clang 19 and AppleClang don't have diagnose_if with diagnostic flags // UNSUPPORTED: clang-19, apple-clang-17 +// ADDITIONAL_COMPILE_FLAGS: -Wno-unused-result + #include <string> #include "test_macros.h" diff --git a/libcxx/test/libcxx/strings/string.view/nonnull.verify.cpp b/libcxx/test/libcxx/strings/string.view/nonnull.verify.cpp index 316c982..ffe0487 100644 --- a/libcxx/test/libcxx/strings/string.view/nonnull.verify.cpp +++ b/libcxx/test/libcxx/strings/string.view/nonnull.verify.cpp @@ -10,8 +10,10 @@ // Ensure that APIs which take a CharT* are diagnosing passing a nullptr to them -// Clang 19 and AppleClang don't have diagnose_if with diagnostic flags -// UNSUPPORTED: clang-19, apple-clang-17 +// AppleClang doesn't have diagnose_if with diagnostic flags +// UNSUPPORTED: apple-clang-17 + +// ADDITIONAL_COMPILE_FLAGS: -Wno-unused-result #include <string_view> diff --git a/libcxx/test/libcxx/system_reserved_names.gen.py b/libcxx/test/libcxx/system_reserved_names.gen.py index d69182d..aaede22 100644 --- a/libcxx/test/libcxx/system_reserved_names.gen.py +++ b/libcxx/test/libcxx/system_reserved_names.gen.py @@ -83,7 +83,7 @@ for header in public_headers: // Test that libc++ doesn't use names that collide with FreeBSD system macros. // newlib and picolibc also define these macros -#if !defined(__FreeBSD__) && !defined(_NEWLIB_VERSION) +#if !defined(__FreeBSD__) && !_LIBCPP_LIBC_NEWLIB # define __null_sentinel SYSTEM_RESERVED_NAME # define __generic SYSTEM_RESERVED_NAME #endif @@ -122,7 +122,7 @@ for header in public_headers: #endif // Newlib & picolibc use __input as a parameter name of a64l & l64a -#ifndef _NEWLIB_VERSION +#if !_LIBCPP_LIBC_NEWLIB # define __input SYSTEM_RESERVED_NAME #endif #define __output SYSTEM_RESERVED_NAME diff --git a/libcxx/test/libcxx/thread/nodiscard.verify.cpp b/libcxx/test/libcxx/thread/nodiscard.verify.cpp new file mode 100644 index 0000000..19e43f8 --- /dev/null +++ b/libcxx/test/libcxx/thread/nodiscard.verify.cpp @@ -0,0 +1,144 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03 +// UNSUPPORTED: no-threads + +// Check that functions are marked [[nodiscard]] + +#include <chrono> +#include <barrier> +#include <latch> +#include <mutex> +#include <semaphore> +#include <thread> + +#include "test_macros.h" + +const auto timePoint = std::chrono::steady_clock::now(); + +void test() { + // Threads + { + std::thread th; + + th.joinable(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + th.get_id(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + th.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + th.hardware_concurrency(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } +#if TEST_STD_VER >= 20 + { + std::jthread jt; + + jt.joinable(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + jt.get_id(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + jt.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + jt.get_stop_source(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + jt.get_stop_token(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + jt.hardware_concurrency(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } +#endif + + // Mutual exclusion + + { // <mutex> + std::mutex m; + + m.try_lock(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + m.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + { + std::recursive_mutex m; + + m.try_lock(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + m.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + { + std::timed_mutex m; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + m.try_lock(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + m.try_lock_for(std::chrono::nanoseconds{82}); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + m.try_lock_until(timePoint); + } + { + std::recursive_timed_mutex m; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + m.try_lock(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + m.try_lock_for(std::chrono::nanoseconds{82}); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + m.try_lock_until(timePoint); + } + { + std::mutex m1; + std::mutex m2; + std::mutex m3; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::try_lock(m1, m2); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::try_lock(m1, m2, m3); + } + + // Condition variables + + { // <condition_variable> + std::condition_variable cv; + + cv.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + +#if TEST_STD_VER >= 20 + + // Semaphores + + { // <semaphore> + std::counting_semaphore<> cs{0}; + + cs.max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + cs.try_acquire_for(std::chrono::nanoseconds{82}); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + cs.try_acquire(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + cs.try_acquire_until(timePoint); + + std::binary_semaphore bs{0}; + + bs.max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + bs.try_acquire_for(std::chrono::nanoseconds{82}); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + bs.try_acquire(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + bs.try_acquire_until(timePoint); + } + + // Latches and barriers + + { // <barrier> + std::barrier<> b{94}; + + b.max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + { // <latch> + std::latch l{94}; + + l.max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + l.try_wait(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + +#endif +} diff --git a/libcxx/test/libcxx/transitive_includes.gen.py b/libcxx/test/libcxx/transitive_includes.gen.py index 6ed35af..2b643e1 100644 --- a/libcxx/test/libcxx/transitive_includes.gen.py +++ b/libcxx/test/libcxx/transitive_includes.gen.py @@ -89,7 +89,7 @@ else: // UNSUPPORTED: LIBCXX-FREEBSD-FIXME // RUN: mkdir %t -// RUN: %{{cxx}} %s %{{flags}} %{{compile_flags}} --trace-includes -fshow-skipped-includes --preprocess > /dev/null 2> %t/trace-includes.txt +// RUN: %{{cxx}} %s %{{flags}} %{{compile_flags}} -Wno-deprecated --trace-includes -fshow-skipped-includes --preprocess > /dev/null 2> %t/trace-includes.txt // RUN: %{{python}} %{{libcxx-dir}}/test/libcxx/transitive_includes/to_csv.py %t/trace-includes.txt > %t/actual_transitive_includes.csv // RUN: cat %{{libcxx-dir}}/test/libcxx/transitive_includes/%{{cxx_std}}.csv | awk '/^{escaped_header} / {{ print }}' > %t/expected_transitive_includes.csv // RUN: diff -w %t/expected_transitive_includes.csv %t/actual_transitive_includes.csv diff --git a/libcxx/test/libcxx/type_traits/is_replaceable.compile.pass.cpp b/libcxx/test/libcxx/type_traits/is_replaceable.compile.pass.cpp deleted file mode 100644 index c04e944..0000000 --- a/libcxx/test/libcxx/type_traits/is_replaceable.compile.pass.cpp +++ /dev/null @@ -1,353 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include <__type_traits/is_replaceable.h> -#include <array> -#include <deque> -#include <exception> -#include <expected> -#include <memory> -#include <optional> -#include <string> -#include <tuple> -#include <type_traits> -#include <variant> -#include <vector> - -#include "constexpr_char_traits.h" -#include "test_allocator.h" -#include "test_macros.h" - -#ifndef TEST_HAS_NO_LOCALIZATION -# include <locale> -#endif - -template <class T> -struct NonPropagatingStatefulMoveAssignAlloc : std::allocator<T> { - using propagate_on_container_move_assignment = std::false_type; - using is_always_equal = std::false_type; - template <class U> - struct rebind { - using other = NonPropagatingStatefulMoveAssignAlloc<U>; - }; -}; - -template <class T> -struct NonPropagatingStatefulCopyAssignAlloc : std::allocator<T> { - using propagate_on_container_copy_assignment = std::false_type; - using is_always_equal = std::false_type; - template <class U> - struct rebind { - using other = NonPropagatingStatefulCopyAssignAlloc<U>; - }; -}; - -template <class T> -struct NonPropagatingStatelessMoveAssignAlloc : std::allocator<T> { - using propagate_on_container_move_assignment = std::false_type; - using is_always_equal = std::true_type; - template <class U> - struct rebind { - using other = NonPropagatingStatelessMoveAssignAlloc<U>; - }; -}; - -template <class T> -struct NonPropagatingStatelessCopyAssignAlloc : std::allocator<T> { - using propagate_on_container_copy_assignment = std::false_type; - using is_always_equal = std::true_type; - template <class U> - struct rebind { - using other = NonPropagatingStatelessCopyAssignAlloc<U>; - }; -}; - -template <class T> -struct NonReplaceableStatelessAlloc : std::allocator<T> { - // Ensure that we don't consider an allocator that is a member of a container to be - // replaceable if it's not replaceable, even if it always compares equal and always propagates. - using propagate_on_container_move_assignment = std::true_type; - using propagate_on_container_copy_assignment = std::true_type; - using is_always_equal = std::true_type; - NonReplaceableStatelessAlloc() = default; - NonReplaceableStatelessAlloc(NonReplaceableStatelessAlloc const&) {} - NonReplaceableStatelessAlloc(NonReplaceableStatelessAlloc&&) = default; - template <class U> - struct rebind { - using other = NonReplaceableStatelessAlloc<U>; - }; -}; -static_assert(!std::__is_replaceable<NonReplaceableStatelessAlloc<int> >::value, ""); - -static_assert(!std::__is_replaceable<test_allocator<char> >::value, ""); // we use that property below - -struct Empty {}; -static_assert(std::__is_replaceable<char>::value, ""); -static_assert(std::__is_replaceable<int>::value, ""); -static_assert(std::__is_replaceable<double>::value, ""); -static_assert(std::__is_replaceable<Empty>::value, ""); - -struct TriviallyCopyable { - char c; - int i; - Empty s; -}; -static_assert(std::__is_replaceable<TriviallyCopyable>::value, ""); - -struct NotTriviallyCopyable { - NotTriviallyCopyable(const NotTriviallyCopyable&); - ~NotTriviallyCopyable(); -}; -static_assert(!std::__is_replaceable<NotTriviallyCopyable>::value, ""); - -struct MoveOnlyTriviallyCopyable { - MoveOnlyTriviallyCopyable(const MoveOnlyTriviallyCopyable&) = delete; - MoveOnlyTriviallyCopyable& operator=(const MoveOnlyTriviallyCopyable&) = delete; - MoveOnlyTriviallyCopyable(MoveOnlyTriviallyCopyable&&) = default; - MoveOnlyTriviallyCopyable& operator=(MoveOnlyTriviallyCopyable&&) = default; -}; -static_assert(std::__is_replaceable<MoveOnlyTriviallyCopyable>::value, ""); - -struct CustomCopyAssignment { - CustomCopyAssignment(const CustomCopyAssignment&) = default; - CustomCopyAssignment(CustomCopyAssignment&&) = default; - CustomCopyAssignment& operator=(const CustomCopyAssignment&); - CustomCopyAssignment& operator=(CustomCopyAssignment&&) = default; -}; -static_assert(!std::__is_replaceable<CustomCopyAssignment>::value, ""); - -struct CustomMoveAssignment { - CustomMoveAssignment(const CustomMoveAssignment&) = default; - CustomMoveAssignment(CustomMoveAssignment&&) = default; - CustomMoveAssignment& operator=(const CustomMoveAssignment&) = default; - CustomMoveAssignment& operator=(CustomMoveAssignment&&); -}; -static_assert(!std::__is_replaceable<CustomMoveAssignment>::value, ""); - -// library-internal types -// ---------------------- - -// __split_buffer -static_assert( - std::__is_replaceable<std::__split_buffer<int, std::allocator<int>, std::__split_buffer_pointer_layout> >::value, - ""); -static_assert(std::__is_replaceable<std::__split_buffer<NotTriviallyCopyable, - std::allocator<NotTriviallyCopyable>, - std::__split_buffer_pointer_layout> >::value, - ""); -static_assert( - !std::__is_replaceable< - std::__split_buffer<int, NonPropagatingStatefulCopyAssignAlloc<int>, std::__split_buffer_pointer_layout > >:: - value, - ""); -static_assert( - !std::__is_replaceable< - std::__split_buffer<int, NonPropagatingStatefulMoveAssignAlloc<int>, std::__split_buffer_pointer_layout > >:: - value, - ""); -static_assert( - std::__is_replaceable< - std::__split_buffer<int, NonPropagatingStatelessCopyAssignAlloc<int>, std::__split_buffer_pointer_layout > >:: - value, - ""); -static_assert( - std::__is_replaceable< - std::__split_buffer<int, NonPropagatingStatelessMoveAssignAlloc<int>, std::__split_buffer_pointer_layout > >:: - value, - ""); - -static_assert( - std::__is_replaceable<std::__split_buffer<int, std::allocator<int>, std::__split_buffer_size_layout> >::value, ""); -static_assert(std::__is_replaceable<std::__split_buffer<NotTriviallyCopyable, - std::allocator<NotTriviallyCopyable>, - std::__split_buffer_size_layout> >::value, - ""); -static_assert( - !std::__is_replaceable< - std::__split_buffer<int, NonPropagatingStatefulCopyAssignAlloc<int>, std::__split_buffer_size_layout > >::value, - ""); -static_assert( - !std::__is_replaceable< - std::__split_buffer<int, NonPropagatingStatefulMoveAssignAlloc<int>, std::__split_buffer_size_layout > >::value, - ""); -static_assert( - std::__is_replaceable< - std::__split_buffer<int, NonPropagatingStatelessCopyAssignAlloc<int>, std::__split_buffer_size_layout > >:: - value, - ""); -static_assert( - std::__is_replaceable< - std::__split_buffer<int, NonPropagatingStatelessMoveAssignAlloc<int>, std::__split_buffer_size_layout > >:: - value, - ""); - -// standard library types -// ---------------------- - -// array -static_assert(std::__is_replaceable<std::array<int, 0> >::value, ""); -static_assert(std::__is_replaceable<std::array<NotTriviallyCopyable, 0> >::value, ""); -static_assert(std::__is_replaceable<std::array<std::unique_ptr<int>, 0> >::value, ""); - -static_assert(std::__is_replaceable<std::array<int, 1> >::value, ""); -static_assert(!std::__is_replaceable<std::array<NotTriviallyCopyable, 1> >::value, ""); -static_assert(std::__is_replaceable<std::array<std::unique_ptr<int>, 1> >::value, ""); - -// basic_string -struct MyChar { - char c; -}; -template <class T> -struct NotReplaceableCharTraits : constexpr_char_traits<T> { - NotReplaceableCharTraits(const NotReplaceableCharTraits&); - NotReplaceableCharTraits& operator=(const NotReplaceableCharTraits&); - ~NotReplaceableCharTraits(); -}; - -static_assert(std::__is_replaceable<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::value, - ""); -static_assert( - std::__is_replaceable<std::basic_string<char, NotReplaceableCharTraits<char>, std::allocator<char> > >::value, ""); -static_assert( - std::__is_replaceable<std::basic_string<MyChar, constexpr_char_traits<MyChar>, std::allocator<MyChar> > >::value, - ""); -static_assert(!std::__is_replaceable<std::basic_string<char, std::char_traits<char>, test_allocator<char> > >::value, - ""); -static_assert(!std::__is_replaceable< - std::basic_string<char, std::char_traits<char>, NonReplaceableStatelessAlloc<char> > >::value, - ""); -static_assert(std::__is_replaceable< - std::basic_string<MyChar, NotReplaceableCharTraits<MyChar>, std::allocator<MyChar> > >::value, - ""); -static_assert( - !std::__is_replaceable< - std::basic_string<char, std::char_traits<char>, NonPropagatingStatefulCopyAssignAlloc<char> > >::value, - ""); -static_assert( - !std::__is_replaceable< - std::basic_string<char, std::char_traits<char>, NonPropagatingStatefulMoveAssignAlloc<char> > >::value, - ""); -static_assert( - std::__is_replaceable< - std::basic_string<char, std::char_traits<char>, NonPropagatingStatelessCopyAssignAlloc<char> > >::value, - ""); -static_assert( - std::__is_replaceable< - std::basic_string<char, std::char_traits<char>, NonPropagatingStatelessMoveAssignAlloc<char> > >::value, - ""); - -// deque -static_assert(std::__is_replaceable<std::deque<int> >::value, ""); -static_assert(std::__is_replaceable<std::deque<NotTriviallyCopyable> >::value, ""); -static_assert(!std::__is_replaceable<std::deque<int, test_allocator<int> > >::value, ""); -static_assert(!std::__is_replaceable<std::deque<int, NonReplaceableStatelessAlloc<int> > >::value, ""); -static_assert(!std::__is_replaceable<std::deque<int, NonPropagatingStatefulCopyAssignAlloc<int> > >::value, ""); -static_assert(!std::__is_replaceable<std::deque<int, NonPropagatingStatefulMoveAssignAlloc<int> > >::value, ""); -static_assert(std::__is_replaceable<std::deque<int, NonPropagatingStatelessCopyAssignAlloc<int> > >::value, ""); -static_assert(std::__is_replaceable<std::deque<int, NonPropagatingStatelessMoveAssignAlloc<int> > >::value, ""); - -// exception_ptr -#ifndef _LIBCPP_ABI_MICROSOFT -static_assert(std::__is_replaceable<std::exception_ptr>::value, ""); -#endif - -// expected -#if TEST_STD_VER >= 23 -static_assert(std::__is_replaceable<std::expected<int, int> >::value); -static_assert(!std::__is_replaceable<std::expected<CustomCopyAssignment, int>>::value); -static_assert(!std::__is_replaceable<std::expected<int, CustomCopyAssignment>>::value); -static_assert(!std::__is_replaceable<std::expected<CustomCopyAssignment, CustomCopyAssignment>>::value); -#endif - -// locale -#ifndef TEST_HAS_NO_LOCALIZATION -static_assert(std::__is_replaceable<std::locale>::value, ""); -#endif - -// optional -#if TEST_STD_VER >= 17 -static_assert(std::__is_replaceable<std::optional<int>>::value, ""); -static_assert(!std::__is_replaceable<std::optional<CustomCopyAssignment>>::value, ""); -#endif - -// pair -static_assert(std::__is_replaceable<std::pair<int, int> >::value, ""); -static_assert(!std::__is_replaceable<std::pair<CustomCopyAssignment, int> >::value, ""); -static_assert(!std::__is_replaceable<std::pair<int, CustomCopyAssignment> >::value, ""); -static_assert(!std::__is_replaceable<std::pair<CustomCopyAssignment, CustomCopyAssignment> >::value, ""); - -// shared_ptr -static_assert(std::__is_replaceable<std::shared_ptr<int> >::value, ""); - -// tuple -#if TEST_STD_VER >= 11 -static_assert(std::__is_replaceable<std::tuple<> >::value, ""); - -static_assert(std::__is_replaceable<std::tuple<int> >::value, ""); -static_assert(!std::__is_replaceable<std::tuple<CustomCopyAssignment> >::value, ""); - -static_assert(std::__is_replaceable<std::tuple<int, int> >::value, ""); -static_assert(!std::__is_replaceable<std::tuple<CustomCopyAssignment, int> >::value, ""); -static_assert(!std::__is_replaceable<std::tuple<int, CustomCopyAssignment> >::value, ""); -static_assert(!std::__is_replaceable<std::tuple<CustomCopyAssignment, CustomCopyAssignment> >::value, ""); -#endif // TEST_STD_VER >= 11 - -// unique_ptr -struct NonReplaceableDeleter { - NonReplaceableDeleter(const NonReplaceableDeleter&); - NonReplaceableDeleter& operator=(const NonReplaceableDeleter&); - ~NonReplaceableDeleter(); - - template <class T> - void operator()(T*); -}; - -struct NonReplaceablePointer { - struct pointer { - pointer(const pointer&); - pointer& operator=(const pointer&); - ~pointer(); - }; - - template <class T> - void operator()(T*); -}; - -static_assert(std::__is_replaceable<std::unique_ptr<int> >::value, ""); -static_assert(std::__is_replaceable<std::unique_ptr<CustomCopyAssignment> >::value, ""); -static_assert(std::__is_replaceable<std::unique_ptr<int[]> >::value, ""); -static_assert(!std::__is_replaceable<std::unique_ptr<int, NonReplaceableDeleter> >::value, ""); -static_assert(!std::__is_replaceable<std::unique_ptr<int[], NonReplaceableDeleter> >::value, ""); -static_assert(!std::__is_replaceable<std::unique_ptr<int, NonReplaceablePointer> >::value, ""); -static_assert(!std::__is_replaceable<std::unique_ptr<int[], NonReplaceablePointer> >::value, ""); - -// variant -#if TEST_STD_VER >= 17 -static_assert(std::__is_replaceable<std::variant<int> >::value, ""); -static_assert(!std::__is_replaceable<std::variant<CustomCopyAssignment> >::value, ""); - -static_assert(std::__is_replaceable<std::variant<int, int> >::value, ""); -static_assert(!std::__is_replaceable<std::variant<CustomCopyAssignment, int> >::value, ""); -static_assert(!std::__is_replaceable<std::variant<int, CustomCopyAssignment> >::value, ""); -static_assert(!std::__is_replaceable<std::variant<CustomCopyAssignment, CustomCopyAssignment> >::value, ""); -#endif // TEST_STD_VER >= 17 - -// vector -static_assert(std::__is_replaceable<std::vector<int> >::value, ""); -static_assert(std::__is_replaceable<std::vector<CustomCopyAssignment> >::value, ""); -static_assert(!std::__is_replaceable<std::vector<int, test_allocator<int> > >::value, ""); -static_assert(!std::__is_replaceable<std::vector<int, NonReplaceableStatelessAlloc<int> > >::value, ""); -static_assert(!std::__is_replaceable<std::vector<int, NonPropagatingStatefulCopyAssignAlloc<int> > >::value, ""); -static_assert(!std::__is_replaceable<std::vector<int, NonPropagatingStatefulMoveAssignAlloc<int> > >::value, ""); -static_assert(std::__is_replaceable<std::vector<int, NonPropagatingStatelessCopyAssignAlloc<int> > >::value, ""); -static_assert(std::__is_replaceable<std::vector<int, NonPropagatingStatelessMoveAssignAlloc<int> > >::value, ""); - -// weak_ptr -static_assert(std::__is_replaceable<std::weak_ptr<CustomCopyAssignment> >::value, ""); - -// TODO: Mark all the replaceable STL types as such diff --git a/libcxx/test/libcxx/utilities/any/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/any/nodiscard.verify.cpp new file mode 100644 index 0000000..13a67bd --- /dev/null +++ b/libcxx/test/libcxx/utilities/any/nodiscard.verify.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++17 + +// Check that functions are marked [[nodiscard]] + +#include <any> +#include <utility> +#include <vector> + +#include "test_macros.h" + +void test() { + std::any a{94}; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.has_value(); +#if !defined(TEST_HAS_NO_RTTI) + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.type(); +#endif + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::make_any<int>(82); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::make_any<std::vector<int>>({94, 82, 50}); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::any_cast<const int&>(std::as_const(a)); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::any_cast<int&>(a); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::any_cast<int&&>(std::move(a)); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::any_cast<int*>(&a); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::any_cast<const int*>(&std::as_const(a)); +} diff --git a/libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp new file mode 100644 index 0000000..4ca52ac --- /dev/null +++ b/libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++14 + +// <utility> + +// Check that functions are marked [[nodiscard]] + +#include <utility> + +void test() { + std::integer_sequence<int, 49, 82, 94> seq; + + seq.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +} diff --git a/libcxx/test/libcxx/utilities/optional/optional.iterator/iterator.compile.pass.cpp b/libcxx/test/libcxx/utilities/optional/optional.iterator/iterator.compile.pass.cpp index 3cdd755..b604579 100644 --- a/libcxx/test/libcxx/utilities/optional/optional.iterator/iterator.compile.pass.cpp +++ b/libcxx/test/libcxx/utilities/optional/optional.iterator/iterator.compile.pass.cpp @@ -23,8 +23,7 @@ concept has_iterator_aliases = requires { static_assert(has_iterator_aliases<std::optional<int>>); static_assert(has_iterator_aliases<std::optional<const int>>); - -// TODO: Uncomment these once P2988R12 is implemented, as they would be testing optional<T&> - -// static_assert(!has_iterator_aliases<std::optional<int (&)[]>>); -// static_assert(!has_iterator_aliases<std::optional<void (&)(int, char)>>); +static_assert(has_iterator_aliases<std::optional<int&>>); +static_assert(has_iterator_aliases<std::optional<const int&>>); +static_assert(!has_iterator_aliases<std::optional<int (&)[1]>>); +static_assert(!has_iterator_aliases<std::optional<int (&)()>>); diff --git a/libcxx/test/libcxx/utilities/optional/optional.object/optional.object.observe/value_or.compile.pass.cpp b/libcxx/test/libcxx/utilities/optional/optional.object/optional.object.observe/value_or.compile.pass.cpp new file mode 100644 index 0000000..25df0dd --- /dev/null +++ b/libcxx/test/libcxx/utilities/optional/optional.object/optional.object.observe/value_or.compile.pass.cpp @@ -0,0 +1,28 @@ + +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++26 + +// <optional> + +// template <class U> T optional<T>::value_or(U&&); + +#include <concepts> +#include <optional> + +template <typename Opt, typename T> +concept has_value_or = requires(Opt opt, T&& t) { + { opt.value_or(t) } -> std::same_as<T>; +}; + +static_assert(has_value_or<std::optional<int>, int>); +static_assert(has_value_or<std::optional<int&>, int&>); +static_assert(has_value_or<std::optional<const int&>, const int&>); +static_assert(!has_value_or<std::optional<int (&)[1]>&&, int (&)[1]>); +static_assert(!has_value_or<std::optional<int (&)()>&&, int (&)()>); diff --git a/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp new file mode 100644 index 0000000..6e713fe --- /dev/null +++ b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp @@ -0,0 +1,165 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03 + +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + +// <memory> + +// Check that functions are marked [[nodiscard]] + +#include <memory> +#include <utility> + +#include "test_macros.h" + +void test() { + { // [unique.ptr] + std::unique_ptr<int> uPtr; + + *uPtr; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + uPtr.get(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + uPtr.get_deleter(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + const std::unique_ptr<int> cuPtr; + cuPtr.get_deleter(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + +#if TEST_STD_VER >= 14 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::make_unique<int>(94); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::make_unique<int[]>(82); +#endif +#if TEST_STD_VER >= 20 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::make_unique_for_overwrite<int>(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::make_unique_for_overwrite<int[]>(5); +#endif + + std::hash<std::unique_ptr<int>> hash; + hash(uPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + { // [util.smartptr.weak.bad] + std::bad_weak_ptr bwp; + + bwp.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + { // [util.sharedptr] + std::shared_ptr<int[]> sPtr; + + sPtr.get(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + *sPtr; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sPtr.use_count(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sPtr.unique(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sPtr.owner_before(std::shared_ptr<int>()); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + sPtr.owner_before(std::weak_ptr<int>()); +#if TEST_STD_VER >= 17 + sPtr[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::allocate_shared<int>(std::allocator<int>(), 5); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::make_shared<int>(); +#if TEST_STD_VER >= 20 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::allocate_shared_for_overwrite<int>(std::allocator<int>()); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::make_shared_for_overwrite<int>(); + + // Bounded array variants + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::allocate_shared<int[5]>(std::allocator<int>()); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::allocate_shared<int[5]>(std::allocator<int>(), 5); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::allocate_shared_for_overwrite<int[5]>(std::allocator<int>()); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::make_shared<int[5]>(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::make_shared<int[5]>(94); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::make_shared_for_overwrite<int[5]>(); + + // Unbounded array variants + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::allocate_shared<int[]>(std::allocator<int>(), 5); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::allocate_shared<int[]>(std::allocator<int>(), 5, 94); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::allocate_shared_for_overwrite<int[]>(std::allocator<int>(), 5); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::make_shared<int[]>(5); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::make_shared<int[]>(5, 82); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::make_shared_for_overwrite<int[]>(5); +#endif + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::static_pointer_cast<int[]>(sPtr); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::static_pointer_cast<int[]>(std::move(sPtr)); + class Empty {}; + std::shared_ptr<Empty> dsPtr; + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::dynamic_pointer_cast<Empty>(dsPtr); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::dynamic_pointer_cast<Empty>(std::move(dsPtr)); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::const_pointer_cast<int[]>(sPtr); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::const_pointer_cast<int[]>(std::move(sPtr)); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::reinterpret_pointer_cast<int[]>(sPtr); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::reinterpret_pointer_cast<int[]>(std::move(sPtr)); +#if !defined(TEST_HAS_NO_RTTI) + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::get_deleter<int[]>(sPtr); +#endif + + std::hash<std::shared_ptr<int[]>> hash; + hash(sPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + { // [util.smartptr.weak] + std::weak_ptr<int> wPtr; + + wPtr.use_count(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + wPtr.expired(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + wPtr.lock(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + wPtr.owner_before(std::weak_ptr<int>()); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + wPtr.owner_before(std::shared_ptr<int>()); + } + { // [util.smartptr.enab] + class EnableShared : public std::enable_shared_from_this<EnableShared> {}; + EnableShared es; + const EnableShared ces; + + es.shared_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ces.shared_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#if TEST_STD_VER >= 17 + es.weak_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ces.weak_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif + } +#if TEST_STD_VER >= 23 + { // [smartptr.adapt] + std::unique_ptr<int> uPtr; + // [inout.ptr] + std::inout_ptr(uPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // [out.ptr] + std::out_ptr(uPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } +#endif +} diff --git a/libcxx/test/libcxx/utilities/template.bitset/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/template.bitset/nodiscard.verify.cpp new file mode 100644 index 0000000..b13fafe --- /dev/null +++ b/libcxx/test/libcxx/utilities/template.bitset/nodiscard.verify.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// <bitset> + +// Check that functions are marked [[nodiscard]] + +#include <bitset> + +#include "test_macros.h" +#include "test_allocator.h" + +void test() { + std::bitset<11> bs; + const std::bitset<11> cbs; + + // std::bitset<>::reference operator~() const noexcept; + ~bs[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + ~bs; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + bs[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + cbs[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + bs.to_ulong(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + bs.to_ullong(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + struct CharTraits : public std::char_traits<char> {}; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + bs.to_string<char, CharTraits, test_allocator<char> >(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + bs.to_string<char, CharTraits>(); +#if !defined(TEST_HAS_NO_WIDE_CHARACTERS) + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + bs.to_string<wchar_t>(); +#endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + bs.to_string(); + + bs.count(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + bs.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + bs.test(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + bs.all(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + bs.any(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + bs.none(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + bs << 1; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + bs >> 1; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + bs & bs; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + bs | bs; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + bs ^ bs; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::hash<std::bitset<11> > hash; + + hash(bs); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +} diff --git a/libcxx/test/selftest/dsl/dsl.sh.py b/libcxx/test/selftest/dsl/dsl.sh.py index 93f351f..b8ee2ca 100644 --- a/libcxx/test/selftest/dsl/dsl.sh.py +++ b/libcxx/test/selftest/dsl/dsl.sh.py @@ -61,7 +61,7 @@ class SetupConfigs(unittest.TestCase): self.litConfig = lit.LitConfig.LitConfig( progname="lit", path=[], - quiet=False, + diagnostic_level="note", useValgrind=False, valgrindLeakCheck=False, valgrindArgs=[], diff --git a/libcxx/test/selftest/dsl/lit.local.cfg b/libcxx/test/selftest/dsl/lit.local.cfg index dc6887a..73e1c4d 100644 --- a/libcxx/test/selftest/dsl/lit.local.cfg +++ b/libcxx/test/selftest/dsl/lit.local.cfg @@ -10,6 +10,6 @@ # within the test. import base64, lit.util, pickle -base64Encode = lambda s: lit.util.to_string(base64.b64encode(lit.util.to_bytes(s))) +base64Encode = lambda s: base64.b64encode(s).decode("utf-8") escapedSubstitutions = base64Encode(pickle.dumps(config.substitutions)) config.substitutions.append(("%{substitutions}", escapedSubstitutions)) diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp index 890ac23..8354894 100644 --- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp +++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp @@ -32,6 +32,7 @@ #include "almost_satisfies_types.h" #include "test_iterators.h" +#include "type_algorithms.h" struct NotEqualityComparable {}; diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/count.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/count.pass.cpp index ffe3e0e..1561dcf 100644 --- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/count.pass.cpp +++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/count.pass.cpp @@ -19,6 +19,7 @@ #include <algorithm> #include <cassert> #include <cstddef> +#include <cstdint> #include <vector> #include "sized_allocator.h" diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp index 2c1346a..9d9d7ed 100644 --- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp +++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp @@ -26,6 +26,7 @@ #include <array> #include <cassert> #include <cstddef> +#include <cstdint> #include <ranges> #include <vector> diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.ends_with/ranges.ends_with.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.ends_with/ranges.ends_with.pass.cpp index 199e6a7..76c62ff 100644 --- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.ends_with/ranges.ends_with.pass.cpp +++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.ends_with/ranges.ends_with.pass.cpp @@ -25,8 +25,10 @@ #include <array> #include <chrono> #include <ranges> + #include "almost_satisfies_types.h" #include "test_iterators.h" +#include "type_algorithms.h" using namespace std::chrono; diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.starts_with/ranges.starts_with.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.starts_with/ranges.starts_with.pass.cpp index 0f2284e..172fa82 100644 --- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.starts_with/ranges.starts_with.pass.cpp +++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.starts_with/ranges.starts_with.pass.cpp @@ -27,6 +27,7 @@ #include "almost_satisfies_types.h" #include "test_iterators.h" +#include "type_algorithms.h" template <class Iter1, class Sent1 = Iter1, class Iter2 = int*, class Sent2 = Iter2> concept HasStartsWithIt = requires(Iter1 first1, Sent1 last1, Iter2 first2, Sent2 last2) { diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.partitions/pstl.is_partitioned.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.partitions/pstl.is_partitioned.pass.cpp index a80e2f6..b64242d 100644 --- a/libcxx/test/std/algorithms/alg.sorting/alg.partitions/pstl.is_partitioned.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.partitions/pstl.is_partitioned.pass.cpp @@ -20,6 +20,7 @@ #include "test_iterators.h" #include "test_execution_policies.h" +#include "type_algorithms.h" template <class Iter> struct Test { diff --git a/libcxx/test/std/algorithms/robust_against_nonbool.compile.pass.cpp b/libcxx/test/std/algorithms/robust_against_nonbool.compile.pass.cpp new file mode 100644 index 0000000..e7c32d2 --- /dev/null +++ b/libcxx/test/std/algorithms/robust_against_nonbool.compile.pass.cpp @@ -0,0 +1,136 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// <algorithm> +// +// Algorithms that take predicates should support predicates that return a non-boolean value as long as the +// returned type is implicitly convertible to bool. + +#include <algorithm> + +#include <initializer_list> + +#include "boolean_testable.h" + +using Value = StrictComparable<int>; +using Iterator = StrictBooleanIterator<Value*>; +auto pred1 = StrictUnaryPredicate; +auto pred2 = StrictBinaryPredicate; + +void f(Iterator it, Iterator out, std::size_t n, Value const& val, std::initializer_list<Value> ilist) { + (void)std::any_of(it, it, pred1); + (void)std::all_of(it, it, pred1); + (void)std::none_of(it, it, pred1); + (void)std::find_if(it, it, pred1); + (void)std::find_if_not(it, it, pred1); + (void)std::find_first_of(it, it, it, it); + (void)std::find_first_of(it, it, it, it, pred2); + (void)std::adjacent_find(it, it); + (void)std::adjacent_find(it, it, pred2); + (void)std::mismatch(it, it, it, it); + (void)std::mismatch(it, it, it, it, pred2); + (void)std::mismatch(it, it, it); + (void)std::mismatch(it, it, it); + (void)std::mismatch(it, it, it, pred2); + (void)std::equal(it, it, it, it); + (void)std::equal(it, it, it, it, pred2); + (void)std::equal(it, it, it); + (void)std::equal(it, it, it, pred2); + (void)std::lexicographical_compare(it, it, it, it); + (void)std::lexicographical_compare(it, it, it, it, pred2); + (void)std::partition_point(it, it, pred1); + (void)std::lower_bound(it, it, val); + (void)std::lower_bound(it, it, val, pred2); + (void)std::upper_bound(it, it, val); + (void)std::upper_bound(it, it, val, pred2); + (void)std::equal_range(it, it, val); + (void)std::equal_range(it, it, val, pred2); + (void)std::binary_search(it, it, val); + (void)std::binary_search(it, it, val, pred2); + (void)std::min(val, val); + (void)std::min(val, val, pred2); + (void)std::min(ilist); + (void)std::min(ilist, pred2); + (void)std::max(val, val); + (void)std::max(val, val, pred2); + (void)std::max(ilist); + (void)std::max(ilist, pred2); + (void)std::minmax(val, val); + (void)std::minmax(val, val, pred2); + (void)std::minmax(ilist); + (void)std::minmax(ilist, pred2); + (void)std::min_element(it, it); + (void)std::min_element(it, it, pred2); + (void)std::max_element(it, it); + (void)std::max_element(it, it, pred2); + (void)std::minmax_element(it, it); + (void)std::minmax_element(it, it, pred2); + (void)std::count_if(it, it, pred1); + (void)std::search(it, it, it, it); + (void)std::search(it, it, it, it, pred2); + (void)std::search_n(it, it, n, val); + (void)std::search_n(it, it, n, val, pred2); + (void)std::is_partitioned(it, it, pred1); + (void)std::is_sorted(it, it); + (void)std::is_sorted(it, it, pred2); + (void)std::is_sorted_until(it, it); + (void)std::is_sorted_until(it, it, pred2); + (void)std::is_heap(it, it); + (void)std::is_heap(it, it, pred2); + (void)std::is_heap_until(it, it); + (void)std::is_heap_until(it, it, pred2); + (void)std::clamp(val, val, val); + (void)std::clamp(val, val, val, pred2); + (void)std::is_permutation(it, it, it, it); + (void)std::is_permutation(it, it, it, it, pred2); + (void)std::copy_if(it, it, out, pred1); + (void)std::remove_copy_if(it, it, out, pred1); + (void)std::remove_copy(it, it, out, val); + (void)std::replace(it, it, val, val); + (void)std::replace_if(it, it, pred1, val); + (void)std::replace_copy_if(it, it, out, pred1, val); + (void)std::replace_copy(it, it, out, val, val); + (void)std::unique_copy(it, it, out, pred2); + (void)std::partition_copy(it, it, out, out, pred1); + (void)std::partial_sort_copy(it, it, it, it, pred2); + (void)std::merge(it, it, it, it, out); + (void)std::merge(it, it, it, it, out, pred2); + (void)std::set_difference(it, it, it, it, out, pred2); + (void)std::set_intersection(it, it, it, it, out, pred2); + (void)std::set_symmetric_difference(it, it, it, it, out, pred2); + (void)std::set_union(it, it, it, it, out, pred2); + (void)std::remove_if(it, it, pred1); + (void)std::remove(it, it, val); + (void)std::unique(it, it, pred2); + (void)std::partition(it, it, pred1); + (void)std::stable_partition(it, it, pred1); + (void)std::sort(it, it); + (void)std::sort(it, it, pred2); + (void)std::stable_sort(it, it); + (void)std::stable_sort(it, it, pred2); + (void)std::partial_sort(it, it, it); + (void)std::partial_sort(it, it, it, pred2); + (void)std::nth_element(it, it, it); + (void)std::nth_element(it, it, it, pred2); + (void)std::inplace_merge(it, it, it); + (void)std::inplace_merge(it, it, it, pred2); + (void)std::make_heap(it, it); + (void)std::make_heap(it, it, pred2); + (void)std::push_heap(it, it); + (void)std::push_heap(it, it, pred2); + (void)std::pop_heap(it, it); + (void)std::pop_heap(it, it, pred2); + (void)std::sort_heap(it, it); + (void)std::sort_heap(it, it, pred2); + (void)std::prev_permutation(it, it); + (void)std::prev_permutation(it, it, pred2); + (void)std::next_permutation(it, it); + (void)std::next_permutation(it, it, pred2); +} diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/lost_wakeup.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/lost_wakeup.pass.cpp new file mode 100644 index 0000000..17ad72d --- /dev/null +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/lost_wakeup.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: no-threads +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// This is a stress test for std::atomic::wait for lost wake ups. + +// <atomic> + +#include <atomic> +#include <functional> +#include <thread> +#include <vector> + +#include "make_test_thread.h" + +constexpr int num_waiters = 8; +constexpr int num_iterations = 10'000; + +int main(int, char**) { + for (int run = 0; run < 20; ++run) { + std::atomic<int> waiter_ready(0); + std::atomic<int> state(0); + + auto wait = [&]() { + for (int i = 0; i < num_iterations; ++i) { + auto old_state = state.load(); + waiter_ready.fetch_add(1); + state.wait(old_state); + } + }; + + auto notify = [&] { + for (int i = 0; i < num_iterations; ++i) { + while (waiter_ready.load() < num_waiters) { + } + waiter_ready.store(0); + state.fetch_add(1); + state.notify_all(); + } + }; + + std::vector<std::jthread> threads; + for (int i = 0; i < num_waiters; ++i) + threads.push_back(support::make_test_jthread(wait)); + + threads.push_back(support::make_test_jthread(notify)); + } + + return 0; +} diff --git a/libcxx/test/std/containers/associative/map/map.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/dtor_noexcept.pass.cpp index 8497b94..c9f7f28 100644 --- a/libcxx/test/std/containers/associative/map/map.cons/dtor_noexcept.pass.cpp +++ b/libcxx/test/std/containers/associative/map/map.cons/dtor_noexcept.pass.cpp @@ -12,8 +12,9 @@ // UNSUPPORTED: c++03 -#include <map> #include <cassert> +#include <map> +#include <type_traits> #include "test_macros.h" #include "MoveOnly.h" diff --git a/libcxx/test/std/containers/associative/multimap/multimap.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.cons/dtor_noexcept.pass.cpp index 62afae92..c757bef 100644 --- a/libcxx/test/std/containers/associative/multimap/multimap.cons/dtor_noexcept.pass.cpp +++ b/libcxx/test/std/containers/associative/multimap/multimap.cons/dtor_noexcept.pass.cpp @@ -12,8 +12,9 @@ // UNSUPPORTED: c++03 -#include <map> #include <cassert> +#include <map> +#include <type_traits> #include "test_macros.h" #include "MoveOnly.h" diff --git a/libcxx/test/std/containers/associative/multiset/multiset.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/associative/multiset/multiset.cons/dtor_noexcept.pass.cpp index 987eca0..bf5d256 100644 --- a/libcxx/test/std/containers/associative/multiset/multiset.cons/dtor_noexcept.pass.cpp +++ b/libcxx/test/std/containers/associative/multiset/multiset.cons/dtor_noexcept.pass.cpp @@ -12,8 +12,9 @@ // UNSUPPORTED: c++03 -#include <set> #include <cassert> +#include <set> +#include <type_traits> #include "test_macros.h" #include "MoveOnly.h" diff --git a/libcxx/test/std/containers/associative/set/set.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/associative/set/set.cons/dtor_noexcept.pass.cpp index 63c0433..a382ce6 100644 --- a/libcxx/test/std/containers/associative/set/set.cons/dtor_noexcept.pass.cpp +++ b/libcxx/test/std/containers/associative/set/set.cons/dtor_noexcept.pass.cpp @@ -12,8 +12,9 @@ // UNSUPPORTED: c++03 -#include <set> #include <cassert> +#include <set> +#include <type_traits> #include "test_macros.h" #include "MoveOnly.h" diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp index e8ea20b..9862936 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp @@ -97,7 +97,7 @@ constexpr bool test() { TransparentComparator c(transparent_used); std::flat_map<int, int, TransparentComparator> m(std::sorted_unique, {{1, 1}, {2, 2}, {3, 3}}, c); assert(!transparent_used); - m[ConvertibleTransparent<int>{3}]; + (void)m[ConvertibleTransparent<int>{3}]; assert(transparent_used); } { diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/copy_assign.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/copy_assign.pass.cpp index 8aa2e7b..56231b8 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/copy_assign.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/copy_assign.pass.cpp @@ -12,6 +12,7 @@ // flat_map& operator=(const flat_map& m); +#include <cassert> #include <deque> #include <flat_map> #include <functional> @@ -28,8 +29,8 @@ constexpr void test() { // test_allocator is not propagated using C = test_less<int>; KeyContainer<int, test_allocator<int>> ks({1, 3, 5}, test_allocator<int>(6)); - ValueContainer<char, test_allocator<char>> vs({2, 2, 1}, test_allocator<char>(7)); - using M = std::flat_map<int, char, C, decltype(ks), decltype(vs)>; + ValueContainer<long, test_allocator<long>> vs({2, 2, 1}, test_allocator<long>(7)); + using M = std::flat_map<int, long, C, decltype(ks), decltype(vs)>; auto mo = M(ks, vs, C(5)); auto m = M({{3, 3}, {4, 4}, {5, 5}}, C(3), test_allocator<int>(2)); m = mo; @@ -38,23 +39,23 @@ constexpr void test() { assert(m.keys() == ks); assert(m.values() == vs); assert(m.keys().get_allocator() == test_allocator<int>(2)); - assert(m.values().get_allocator() == test_allocator<char>(2)); + assert(m.values().get_allocator() == test_allocator<long>(2)); // mo is unchanged assert(mo.key_comp() == C(5)); assert(mo.keys() == ks); assert(mo.values() == vs); assert(mo.keys().get_allocator() == test_allocator<int>(6)); - assert(mo.values().get_allocator() == test_allocator<char>(7)); + assert(mo.values().get_allocator() == test_allocator<long>(7)); } { // other_allocator is propagated using C = test_less<int>; using Ks = KeyContainer<int, other_allocator<int>>; - using Vs = ValueContainer<char, other_allocator<char>>; + using Vs = ValueContainer<long, other_allocator<long>>; auto ks = Ks({1, 3, 5}, other_allocator<int>(6)); - auto vs = Vs({2, 2, 1}, other_allocator<char>(7)); - using M = std::flat_map<int, char, C, Ks, Vs>; + auto vs = Vs({2, 2, 1}, other_allocator<long>(7)); + using M = std::flat_map<int, long, C, Ks, Vs>; auto mo = M(Ks(ks, other_allocator<int>(6)), Vs(vs, other_allocator<int>(7)), C(5)); auto m = M({{3, 3}, {4, 4}, {5, 5}}, C(3), other_allocator<int>(2)); m = mo; @@ -63,14 +64,14 @@ constexpr void test() { assert(m.keys() == ks); assert(m.values() == vs); assert(m.keys().get_allocator() == other_allocator<int>(6)); - assert(m.values().get_allocator() == other_allocator<char>(7)); + assert(m.values().get_allocator() == other_allocator<long>(7)); // mo is unchanged assert(mo.key_comp() == C(5)); assert(mo.keys() == ks); assert(mo.values() == vs); assert(mo.keys().get_allocator() == other_allocator<int>(6)); - assert(mo.values().get_allocator() == other_allocator<char>(7)); + assert(mo.values().get_allocator() == other_allocator<long>(7)); } if (!TEST_IS_CONSTANT_EVALUATED) { // comparator is copied and invariant is preserved diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct.pass.cpp index 21166361..7998bef 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct.pass.cpp @@ -33,19 +33,19 @@ using PC = std::pair<const int, long>; void test_copy() { { - std::flat_map<long, short> source = {{1, 2}, {2, 3}}; + std::flat_map<long, int> source = {{1, 2}, {2, 3}}; std::flat_map s(source); ASSERT_SAME_TYPE(decltype(s), decltype(source)); assert(s == source); } { - std::flat_map<long, short, std::greater<long>> source = {{1, 2}, {2, 3}}; + std::flat_map<long, int, std::greater<long>> source = {{1, 2}, {2, 3}}; std::flat_map s{source}; // braces instead of parens ASSERT_SAME_TYPE(decltype(s), decltype(source)); assert(s == source); } { - std::flat_map<long, short, std::greater<long>> source = {{1, 2}, {2, 3}}; + std::flat_map<long, int, std::greater<long>> source = {{1, 2}, {2, 3}}; std::flat_map s(source, std::allocator<int>()); ASSERT_SAME_TYPE(decltype(s), decltype(source)); assert(s == source); @@ -54,14 +54,14 @@ void test_copy() { void test_containers() { std::deque<int, test_allocator<int>> ks({1, 2, 1, INT_MAX, 3}, test_allocator<int>(0, 42)); - std::deque<short, test_allocator<short>> vs({1, 2, 1, 4, 5}, test_allocator<int>(0, 43)); + std::deque<long, test_allocator<long>> vs({1, 2, 1, 4, 5}, test_allocator<int>(0, 43)); std::deque<int, test_allocator<int>> sorted_ks({1, 2, 3, INT_MAX}, test_allocator<int>(0, 42)); - std::deque<short, test_allocator<short>> sorted_vs({1, 2, 5, 4}, test_allocator<int>(0, 43)); - const std::pair<int, short> expected[] = {{1, 1}, {2, 2}, {3, 5}, {INT_MAX, 4}}; + std::deque<long, test_allocator<long>> sorted_vs({1, 2, 5, 4}, test_allocator<int>(0, 43)); + const std::pair<int, long> expected[] = {{1, 1}, {2, 2}, {3, 5}, {INT_MAX, 4}}; { std::flat_map s(ks, vs); - ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::less<int>, decltype(ks), decltype(vs)>); + ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::less<int>, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 43); @@ -69,7 +69,7 @@ void test_containers() { { std::flat_map s(std::sorted_unique, sorted_ks, sorted_vs); - ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::less<int>, decltype(ks), decltype(vs)>); + ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::less<int>, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 43); @@ -77,7 +77,7 @@ void test_containers() { { std::flat_map s(ks, vs, test_allocator<long>(0, 44)); - ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::less<int>, decltype(ks), decltype(vs)>); + ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::less<int>, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 44); assert(s.values().get_allocator().get_id() == 44); @@ -85,7 +85,7 @@ void test_containers() { { std::flat_map s(std::sorted_unique, sorted_ks, sorted_vs, test_allocator<long>(0, 44)); - ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::less<int>, decltype(ks), decltype(vs)>); + ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::less<int>, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 44); assert(s.values().get_allocator().get_id() == 44); @@ -94,14 +94,14 @@ void test_containers() { void test_containers_compare() { std::deque<int, test_allocator<int>> ks({1, 2, 1, INT_MAX, 3}, test_allocator<int>(0, 42)); - std::deque<short, test_allocator<short>> vs({1, 2, 1, 4, 5}, test_allocator<int>(0, 43)); + std::deque<long, test_allocator<long>> vs({1, 2, 1, 4, 5}, test_allocator<int>(0, 43)); std::deque<int, test_allocator<int>> sorted_ks({INT_MAX, 3, 2, 1}, test_allocator<int>(0, 42)); - std::deque<short, test_allocator<short>> sorted_vs({4, 5, 2, 1}, test_allocator<int>(0, 43)); - const std::pair<int, short> expected[] = {{INT_MAX, 4}, {3, 5}, {2, 2}, {1, 1}}; + std::deque<long, test_allocator<long>> sorted_vs({4, 5, 2, 1}, test_allocator<int>(0, 43)); + const std::pair<int, long> expected[] = {{INT_MAX, 4}, {3, 5}, {2, 2}, {1, 1}}; { std::flat_map s(ks, vs, std::greater<int>()); - ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::greater<int>, decltype(ks), decltype(vs)>); + ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::greater<int>, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 43); @@ -109,7 +109,7 @@ void test_containers_compare() { { std::flat_map s(std::sorted_unique, sorted_ks, sorted_vs, std::greater<int>()); - ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::greater<int>, decltype(ks), decltype(vs)>); + ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::greater<int>, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 43); @@ -117,7 +117,7 @@ void test_containers_compare() { { std::flat_map s(ks, vs, std::greater<int>(), test_allocator<long>(0, 44)); - ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::greater<int>, decltype(ks), decltype(vs)>); + ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::greater<int>, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 44); assert(s.values().get_allocator().get_id() == 44); @@ -125,7 +125,7 @@ void test_containers_compare() { { std::flat_map s(std::sorted_unique, sorted_ks, sorted_vs, std::greater<int>(), test_allocator<long>(0, 44)); - ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::greater<int>, decltype(ks), decltype(vs)>); + ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::greater<int>, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 44); assert(s.values().get_allocator().get_id() == 44); @@ -280,11 +280,11 @@ void test_initializer_list_compare() { } void test_from_range() { - std::list<std::pair<int, short>> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}}; - const std::pair<int, short> expected[] = {{1, 1}, {2, 2}, {3, 5}, {INT_MAX, 4}}; + std::list<std::pair<int, long>> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}}; + const std::pair<int, long> expected[] = {{1, 1}, {2, 2}, {3, 5}, {INT_MAX, 4}}; { std::flat_map s(std::from_range, r); - ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::less<int>>); + ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::less<int>>); assert(std::ranges::equal(s, expected)); } { @@ -292,10 +292,10 @@ void test_from_range() { ASSERT_SAME_TYPE( decltype(s), std::flat_map<int, - short, + long, std::less<int>, std::vector<int, test_allocator<int>>, - std::vector<short, test_allocator<short>>>); + std::vector<long, test_allocator<long>>>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 42); @@ -303,11 +303,11 @@ void test_from_range() { } void test_from_range_compare() { - std::list<std::pair<int, short>> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}}; - const std::pair<int, short> expected[] = {{INT_MAX, 4}, {3, 5}, {2, 2}, {1, 1}}; + std::list<std::pair<int, long>> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}}; + const std::pair<int, long> expected[] = {{INT_MAX, 4}, {3, 5}, {2, 2}, {1, 1}}; { std::flat_map s(std::from_range, r, std::greater<int>()); - ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, short, std::greater<int>>); + ASSERT_SAME_TYPE(decltype(s), std::flat_map<int, long, std::greater<int>>); assert(std::ranges::equal(s, expected)); } { @@ -315,10 +315,10 @@ void test_from_range_compare() { ASSERT_SAME_TYPE( decltype(s), std::flat_map<int, - short, + long, std::greater<int>, std::vector<int, test_allocator<int>>, - std::vector<short, test_allocator<short>>>); + std::vector<long, test_allocator<long>>>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 42); diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct_pmr.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct_pmr.pass.cpp index 11c18ac..97eeec4 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct_pmr.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/deduct_pmr.pass.cpp @@ -32,19 +32,19 @@ using PC = std::pair<const int, long>; void test_containers() { std::deque<int, test_allocator<int>> ks({1, 2, 1, INT_MAX, 3}, test_allocator<int>(0, 42)); - std::deque<short, test_allocator<short>> vs({1, 2, 1, 4, 5}, test_allocator<int>(0, 43)); + std::deque<long, test_allocator<long>> vs({1, 2, 1, 4, 5}, test_allocator<int>(0, 43)); std::deque<int, test_allocator<int>> sorted_ks({1, 2, 3, INT_MAX}, test_allocator<int>(0, 42)); - std::deque<short, test_allocator<short>> sorted_vs({1, 2, 5, 4}, test_allocator<int>(0, 43)); - const std::pair<int, short> expected[] = {{1, 1}, {2, 2}, {3, 5}, {INT_MAX, 4}}; + std::deque<long, test_allocator<long>> sorted_vs({1, 2, 5, 4}, test_allocator<int>(0, 43)); + const std::pair<int, long> expected[] = {{1, 1}, {2, 2}, {3, 5}, {INT_MAX, 4}}; { std::pmr::monotonic_buffer_resource mr; std::pmr::monotonic_buffer_resource mr2; std::pmr::deque<int> pks(ks.begin(), ks.end(), &mr); - std::pmr::deque<short> pvs(vs.begin(), vs.end(), &mr); + std::pmr::deque<long> pvs(vs.begin(), vs.end(), &mr); std::flat_map s(std::move(pks), std::move(pvs), &mr2); ASSERT_SAME_TYPE( - decltype(s), std::flat_map<int, short, std::less<int>, std::pmr::deque<int>, std::pmr::deque<short>>); + decltype(s), std::flat_map<int, long, std::less<int>, std::pmr::deque<int>, std::pmr::deque<long>>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().resource() == &mr2); assert(s.values().get_allocator().resource() == &mr2); @@ -53,11 +53,11 @@ void test_containers() { std::pmr::monotonic_buffer_resource mr; std::pmr::monotonic_buffer_resource mr2; std::pmr::deque<int> pks(sorted_ks.begin(), sorted_ks.end(), &mr); - std::pmr::deque<short> pvs(sorted_vs.begin(), sorted_vs.end(), &mr); + std::pmr::deque<long> pvs(sorted_vs.begin(), sorted_vs.end(), &mr); std::flat_map s(std::sorted_unique, std::move(pks), std::move(pvs), &mr2); ASSERT_SAME_TYPE( - decltype(s), std::flat_map<int, short, std::less<int>, std::pmr::deque<int>, std::pmr::deque<short>>); + decltype(s), std::flat_map<int, long, std::less<int>, std::pmr::deque<int>, std::pmr::deque<long>>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().resource() == &mr2); assert(s.values().get_allocator().resource() == &mr2); @@ -66,19 +66,19 @@ void test_containers() { void test_containers_compare() { std::deque<int, test_allocator<int>> ks({1, 2, 1, INT_MAX, 3}, test_allocator<int>(0, 42)); - std::deque<short, test_allocator<short>> vs({1, 2, 1, 4, 5}, test_allocator<int>(0, 43)); + std::deque<long, test_allocator<long>> vs({1, 2, 1, 4, 5}, test_allocator<int>(0, 43)); std::deque<int, test_allocator<int>> sorted_ks({INT_MAX, 3, 2, 1}, test_allocator<int>(0, 42)); - std::deque<short, test_allocator<short>> sorted_vs({4, 5, 2, 1}, test_allocator<int>(0, 43)); - const std::pair<int, short> expected[] = {{INT_MAX, 4}, {3, 5}, {2, 2}, {1, 1}}; + std::deque<long, test_allocator<long>> sorted_vs({4, 5, 2, 1}, test_allocator<int>(0, 43)); + const std::pair<int, long> expected[] = {{INT_MAX, 4}, {3, 5}, {2, 2}, {1, 1}}; { std::pmr::monotonic_buffer_resource mr; std::pmr::monotonic_buffer_resource mr2; std::pmr::deque<int> pks(ks.begin(), ks.end(), &mr); - std::pmr::deque<short> pvs(vs.begin(), vs.end(), &mr); + std::pmr::deque<long> pvs(vs.begin(), vs.end(), &mr); std::flat_map s(std::move(pks), std::move(pvs), std::greater<int>(), &mr2); ASSERT_SAME_TYPE( - decltype(s), std::flat_map<int, short, std::greater<int>, std::pmr::deque<int>, std::pmr::deque<short>>); + decltype(s), std::flat_map<int, long, std::greater<int>, std::pmr::deque<int>, std::pmr::deque<long>>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().resource() == &mr2); assert(s.values().get_allocator().resource() == &mr2); @@ -87,11 +87,11 @@ void test_containers_compare() { std::pmr::monotonic_buffer_resource mr; std::pmr::monotonic_buffer_resource mr2; std::pmr::deque<int> pks(sorted_ks.begin(), sorted_ks.end(), &mr); - std::pmr::deque<short> pvs(sorted_vs.begin(), sorted_vs.end(), &mr); + std::pmr::deque<long> pvs(sorted_vs.begin(), sorted_vs.end(), &mr); std::flat_map s(std::sorted_unique, std::move(pks), std::move(pvs), std::greater<int>(), &mr2); ASSERT_SAME_TYPE( - decltype(s), std::flat_map<int, short, std::greater<int>, std::pmr::deque<int>, std::pmr::deque<short>>); + decltype(s), std::flat_map<int, long, std::greater<int>, std::pmr::deque<int>, std::pmr::deque<long>>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().resource() == &mr2); assert(s.values().get_allocator().resource() == &mr2); diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/dtor_noexcept.pass.cpp index 4562b01..9e81984 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/dtor_noexcept.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/dtor_noexcept.pass.cpp @@ -17,6 +17,7 @@ #include <flat_map> #include <functional> #include <vector> +#include <type_traits> #include "test_macros.h" #include "MoveOnly.h" diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/initializer_list.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/initializer_list.pass.cpp index aea2002..ef49a6e 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/initializer_list.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/initializer_list.pass.cpp @@ -37,24 +37,24 @@ struct DefaultCtableComp { template <template <class...> class KeyContainer, template <class...> class ValueContainer> constexpr void test() { - std::pair<int, short> expected[] = {{1, 1}, {2, 2}, {3, 3}, {5, 2}}; + std::pair<int, long> expected[] = {{1, 1}, {2, 2}, {3, 3}, {5, 2}}; { // flat_map(initializer_list<value_type>); - using M = std::flat_map<int, short>; - std::initializer_list<std::pair<int, short>> il = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}; + using M = std::flat_map<int, long>; + std::initializer_list<std::pair<int, long>> il = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}; M m(il); assert(std::equal(m.begin(), m.end(), expected, expected + 4)); } { // flat_map(initializer_list<value_type>); // explicit(false) - using M = std::flat_map<int, short>; + using M = std::flat_map<int, long>; M m = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}; assert(std::equal(m.begin(), m.end(), expected, expected + 4)); } { // flat_map(initializer_list<value_type>); - using M = std::flat_map<int, short, std::greater<int>, KeyContainer<int, min_allocator<int>>>; + using M = std::flat_map<int, long, std::greater<int>, KeyContainer<int, min_allocator<int>>>; M m = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}; assert(std::equal(m.rbegin(), m.rend(), expected, expected + 4)); } @@ -79,7 +79,7 @@ constexpr void test() { { // flat_map(initializer_list<value_type>, const key_compare&); using C = test_less<int>; - using M = std::flat_map<int, short, C>; + using M = std::flat_map<int, long, C>; auto m = M({{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}, C(10)); assert(std::equal(m.begin(), m.end(), expected, expected + 4)); assert(m.key_comp() == C(10)); @@ -92,7 +92,7 @@ constexpr void test() { if (!TEST_IS_CONSTANT_EVALUATED) { // flat_map(initializer_list<value_type>, const key_compare&); // Sorting uses the comparator that was passed in - using M = std::flat_map<int, short, std::function<bool(int, int)>, KeyContainer<int, min_allocator<int>>>; + using M = std::flat_map<int, long, std::function<bool(int, int)>, KeyContainer<int, min_allocator<int>>>; auto m = M({{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}, std::greater<int>()); assert(std::equal(m.rbegin(), m.rend(), expected, expected + 4)); assert(m.key_comp()(2, 1) == true); diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter.pass.cpp index 0dce4f1..cb6d187 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter.pass.cpp @@ -101,19 +101,19 @@ constexpr void test() { template <template <class...> class KeyContainer, template <class...> class ValueContainer> constexpr void test_alloc() { - using P = std::pair<int, short>; + using P = std::pair<int, long>; P ar[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7}, {3, 8}, {3, 9}}; { // flat_map(InputIterator , InputIterator, const Allocator&) using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_map<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_map<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>; auto m = M(ar, ar + 9, A1(5)); assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 2, 3})); check_possible_values( m.values(), - std::vector<std::vector<short>>{ + std::vector<std::vector<long>>{ {1, 2, 3}, {4, 5, 7}, {6, 8, 9}, @@ -125,13 +125,13 @@ constexpr void test_alloc() { // flat_map(InputIterator , InputIterator, const Allocator&) // explicit(false) using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_map<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_map<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>; M m = {ar, ar + 9, A1(5)}; // implicit ctor assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 2, 3})); check_possible_values( m.values(), - std::vector<std::vector<short>>{ + std::vector<std::vector<long>>{ {1, 2, 3}, {4, 5, 7}, {6, 8, 9}, @@ -143,13 +143,13 @@ constexpr void test_alloc() { // flat_map(InputIterator , InputIterator, const key_compare&, const Allocator&) using C = test_less<int>; using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_map<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_map<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>; auto m = M(ar, ar + 9, C(3), A1(5)); assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 2, 3})); check_possible_values( m.values(), - std::vector<std::vector<short>>{ + std::vector<std::vector<long>>{ {1, 2, 3}, {4, 5, 7}, {6, 8, 9}, @@ -162,13 +162,13 @@ constexpr void test_alloc() { // flat_map(InputIterator , InputIterator, const key_compare&, const Allocator&) // explicit(false) using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_map<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_map<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>; M m = {ar, ar + 9, {}, A2(5)}; // implicit ctor assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 2, 3})); check_possible_values( m.values(), - std::vector<std::vector<short>>{ + std::vector<std::vector<long>>{ {1, 2, 3}, {4, 5, 7}, {6, 8, 9}, diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/move_assign.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/move_assign.pass.cpp index 633c73e..dc3c2e18 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/move_assign.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/move_assign.pass.cpp @@ -31,8 +31,8 @@ constexpr void test() { { using C = test_less<int>; using A1 = test_allocator<int>; - using A2 = test_allocator<char>; - using M = std::flat_map<int, char, C, KeyContainer<int, A1>, ValueContainer<char, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_map<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>; M mo = M({{1, 1}, {2, 3}, {3, 2}}, C(5), A1(7)); M m = M({}, C(3), A1(7)); m = std::move(mo); @@ -46,8 +46,8 @@ constexpr void test() { { using C = test_less<int>; using A1 = other_allocator<int>; - using A2 = other_allocator<char>; - using M = std::flat_map<int, char, C, KeyContainer<int, A1>, ValueContainer<char, A2>>; + using A2 = other_allocator<long>; + using M = std::flat_map<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>; M mo = M({{4, 5}, {5, 4}}, C(5), A1(7)); M m = M({{1, 1}, {2, 2}, {3, 3}, {4, 4}}, C(3), A1(7)); m = std::move(mo); diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/pmr.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/pmr.pass.cpp index 154af11..f3b9d4f 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/pmr.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/pmr.pass.cpp @@ -166,12 +166,12 @@ int main(int, char**) { } { // flat_map(InputIterator first, InputIterator last, const Allocator& a); - using P = std::pair<int, short>; + using P = std::pair<int, long>; P ar[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7}, {3, 8}, {3, 9}}; P expected[] = {{1, 1}, {2, 4}, {3, 6}}; { // cpp17 iterator - using M = std::flat_map<int, short, std::less<int>, std::pmr::vector<int>, std::pmr::vector<short>>; + using M = std::flat_map<int, long, std::less<int>, std::pmr::vector<int>, std::pmr::vector<long>>; std::pmr::monotonic_buffer_resource mr; std::pmr::vector<M> vm(&mr); vm.emplace_back(cpp17_input_iterator<const P*>(ar), cpp17_input_iterator<const P*>(ar + 9)); @@ -181,7 +181,7 @@ int main(int, char**) { assert(vm[0].values().get_allocator().resource() == &mr); } { - using M = std::flat_map<int, short, std::less<int>, std::pmr::vector<int>, std::pmr::vector<short>>; + using M = std::flat_map<int, long, std::less<int>, std::pmr::vector<int>, std::pmr::vector<long>>; std::pmr::monotonic_buffer_resource mr; std::pmr::vector<M> vm(&mr); vm.emplace_back(ar, ar); @@ -242,12 +242,12 @@ int main(int, char**) { } { // flat_map(from_range_t, R&&, const Alloc&); - using P = std::pair<int, short>; + using P = std::pair<int, long>; P ar[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7}, {3, 8}, {3, 9}}; P expected[] = {{1, 1}, {2, 4}, {3, 6}}; { // input_range - using M = std::flat_map<int, short, std::less<int>, std::pmr::vector<int>, std::pmr::vector<short>>; + using M = std::flat_map<int, long, std::less<int>, std::pmr::vector<int>, std::pmr::vector<long>>; using Iter = cpp20_input_iterator<const P*>; using Sent = sentinel_wrapper<Iter>; using R = std::ranges::subrange<Iter, Sent>; @@ -260,7 +260,7 @@ int main(int, char**) { assert(vm[0].values().get_allocator().resource() == &mr); } { - using M = std::flat_map<int, short, std::less<int>, std::pmr::vector<int>, std::pmr::vector<short>>; + using M = std::flat_map<int, long, std::less<int>, std::pmr::vector<int>, std::pmr::vector<long>>; using R = std::ranges::subrange<const P*>; std::pmr::monotonic_buffer_resource mr; std::pmr::vector<M> vm(&mr); diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/range.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/range.pass.cpp index 9f74873..5ac4f09 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/range.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/range.pass.cpp @@ -152,19 +152,19 @@ constexpr void test() { template <template <class...> class KeyContainer, template <class...> class ValueContainer> constexpr void test_alloc() { - using P = std::pair<int, short>; + using P = std::pair<int, long>; P ar[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7}, {3, 8}, {3, 9}}; { // flat_map(from_range_t, R&&, const Allocator&) using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_map<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_map<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>; using R = std::ranges::subrange<const P*>; auto m = M(std::from_range, R(ar, ar + 9), A1(5)); assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 2, 3})); check_possible_values( m.values(), - std::vector<std::vector<short>>{ + std::vector<std::vector<long>>{ {1, 2, 3}, {4, 5, 7}, {6, 8, 9}, @@ -176,14 +176,14 @@ constexpr void test_alloc() { // flat_map(from_range_t, R&&, const Allocator&) // explicit(false) using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_map<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_map<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>; using R = std::ranges::subrange<const P*>; M m = {std::from_range, R(ar, ar + 9), A1(5)}; // implicit ctor assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 2, 3})); check_possible_values( m.values(), - std::vector<std::vector<short>>{ + std::vector<std::vector<long>>{ {1, 2, 3}, {4, 5, 7}, {6, 8, 9}, @@ -195,14 +195,14 @@ constexpr void test_alloc() { // flat_map(from_range_t, R&&, const key_compare&, const Allocator&) using C = test_less<int>; using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_map<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_map<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>; using R = std::ranges::subrange<const P*>; auto m = M(std::from_range, R(ar, ar + 9), C(3), A1(5)); assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 2, 3})); check_possible_values( m.values(), - std::vector<std::vector<short>>{ + std::vector<std::vector<long>>{ {1, 2, 3}, {4, 5, 7}, {6, 8, 9}, @@ -215,14 +215,14 @@ constexpr void test_alloc() { // flat_map(from_range_t, R&&, const key_compare&, const Allocator&) // explicit(false) using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_map<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_map<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>; using R = std::ranges::subrange<const P*>; M m = {std::from_range, R(ar, ar + 9), {}, A2(5)}; // implicit ctor assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 2, 3})); check_possible_values( m.values(), - std::vector<std::vector<short>>{ + std::vector<std::vector<long>>{ {1, 2, 3}, {4, 5, 7}, {6, 8, 9}, diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_container.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_container.pass.cpp index 4c58359..b0e9c3a 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_container.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_container.pass.cpp @@ -38,9 +38,9 @@ template <template <class...> class KeyContainer, template <class...> class Valu constexpr void test() { { // flat_map(sorted_unique_t, key_container_type , mapped_container_type) - using M = std::flat_map<int, char, std::less<int>, KeyContainer<int>, ValueContainer<char>>; + using M = std::flat_map<int, long, std::less<int>, KeyContainer<int>, ValueContainer<long>>; KeyContainer<int> ks = {1, 2, 4, 10}; - ValueContainer<char> vs = {4, 3, 2, 1}; + ValueContainer<long> vs = {4, 3, 2, 1}; auto ks2 = ks; auto vs2 = vs; @@ -59,8 +59,8 @@ constexpr void test() { // flat_map(sorted_unique_t, key_container_type , mapped_container_type) // non-default container, comparator and allocator type using Ks = KeyContainer<int, min_allocator<int>>; - using Vs = ValueContainer<char, min_allocator<char>>; - using M = std::flat_map<int, char, std::greater<int>, Ks, Vs>; + using Vs = ValueContainer<long, min_allocator<long>>; + using M = std::flat_map<int, long, std::greater<int>, Ks, Vs>; Ks ks = {10, 4, 2, 1}; Vs vs = {1, 2, 3, 4}; auto m = M(std::sorted_unique, ks, vs); @@ -87,9 +87,9 @@ constexpr void test() { { // flat_map(sorted_unique_t, key_container_type , mapped_container_type, key_compare) using C = test_less<int>; - using M = std::flat_map<int, char, C, KeyContainer<int>, ValueContainer<char>>; + using M = std::flat_map<int, long, C, KeyContainer<int>, ValueContainer<long>>; KeyContainer<int> ks = {1, 2, 4, 10}; - ValueContainer<char> vs = {4, 3, 2, 1}; + ValueContainer<long> vs = {4, 3, 2, 1}; auto m = M(std::sorted_unique, ks, vs, C(4)); assert((m == M{{1, 4}, {2, 3}, {4, 2}, {10, 1}})); diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_initializer_list.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_initializer_list.pass.cpp index e8ac5d3..4c1d48c 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_initializer_list.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_initializer_list.pass.cpp @@ -35,8 +35,8 @@ template <class T, class U> constexpr std::initializer_list<std::pair<T, U>> il = {{1, 1}, {2, 2}, {4, 4}, {5, 5}}; constexpr auto il1 = il<int, int>; -constexpr auto il2 = il<int, short>; -constexpr auto il3 = il<short, int>; +constexpr auto il2 = il<int, long>; +constexpr auto il3 = il<long, int>; template <template <class...> class KeyContainer, template <class...> class ValueContainer> constexpr void test() { @@ -73,8 +73,8 @@ constexpr void test() { { // flat_map(sorted_unique_t, initializer_list<value_type>, const Allocator&) using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_map<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_map<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>; auto m = M(std::sorted_unique, il2, A1(5)); auto expected = M{{1, 1}, {2, 2}, {4, 4}, {5, 5}}; assert(m == expected); @@ -91,8 +91,8 @@ constexpr void test() { // flat_map(sorted_unique_t, initializer_list<value_type>, const key_compare&, const Allocator&); using C = test_less<int>; using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_map<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_map<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>; auto m = M(std::sorted_unique, il2, C(3), A1(5)); assert((m == M{{1, 1}, {2, 2}, {4, 4}, {5, 5}})); assert(m.key_comp() == C(3)); @@ -102,9 +102,9 @@ constexpr void test() { { // flat_map(sorted_unique_t, initializer_list<value_type>, const key_compare&, const Allocator&); // explicit(false) - using A1 = test_allocator<short>; + using A1 = test_allocator<long>; using A2 = test_allocator<int>; - using M = std::flat_map<short, int, std::less<int>, KeyContainer<short, A1>, ValueContainer<int, A2>>; + using M = std::flat_map<long, int, std::less<int>, KeyContainer<long, A1>, ValueContainer<int, A2>>; M m = {std::sorted_unique, il3, {}, A1(5)}; // implicit ctor assert((m == M{{1, 1}, {2, 2}, {4, 4}, {5, 5}})); assert(m.keys().get_allocator() == A1(5)); diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_iter_iter.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_iter_iter.pass.cpp index f853a08..4825b6c 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_iter_iter.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/sorted_iter_iter.pass.cpp @@ -69,7 +69,7 @@ constexpr void test() { auto m = M(std::sorted_unique, cpp17_input_iterator<const P*>(ar), cpp17_input_iterator<const P*>(ar + 4), - std::less<int>()); + std::less<Value>()); assert(m == M({{1, 1}, {2, 2}, {4, 4}, {5, 5}}, std::less<>())); assert(m.key_comp()(1, 2) == true); @@ -77,19 +77,19 @@ constexpr void test() { M m2 = {std::sorted_unique, cpp17_input_iterator<const P*>(ar), cpp17_input_iterator<const P*>(ar + 4), - std::less<int>()}; + std::less<Value>()}; assert(m2 == m); } { // flat_map(sorted_unique_t, InputIterator, InputIterator, const key_compare&); // greater - using M = std::flat_map<Key, Value, std::greater<int>, KeyContainer, ValueContainer>; + using M = std::flat_map<Key, Value, std::greater<Value>, KeyContainer, ValueContainer>; using P = std::pair<Key, Value>; P ar[] = {{5, 5}, {4, 4}, {2, 2}, {1, 1}}; auto m = M(std::sorted_unique, cpp17_input_iterator<const P*>(ar), cpp17_input_iterator<const P*>(ar + 4), - std::greater<int>()); + std::greater<Value>()); assert((m == M{{5, 5}, {4, 4}, {2, 2}, {1, 1}})); } { @@ -109,8 +109,8 @@ constexpr void test_alloc() { { // flat_map(sorted_unique_t, InputIterator , InputIterator, const Allocator&) using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_map<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_map<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>; using P = std::pair<int, int>; P ar[] = {{1, 1}, {2, 2}, {4, 4}, {5, 5}}; auto m = M(std::sorted_unique, ar, ar + 4, A1(5)); @@ -129,8 +129,8 @@ constexpr void test_alloc() { // flat_map(sorted_unique_t, InputIterator, InputIterator, const key_compare&, const Allocator&); using C = test_less<int>; using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_map<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_map<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>; using P = std::pair<int, int>; P ar[] = {{1, 1}, {2, 2}, {4, 4}, {5, 5}}; auto m = M(std::sorted_unique, ar, ar + 4, C(3), A1(5)); @@ -142,9 +142,9 @@ constexpr void test_alloc() { { // flat_map(sorted_unique_t, InputIterator, InputIterator, const key_compare&, const Allocator&); // explicit(false) - using A1 = test_allocator<short>; + using A1 = test_allocator<long>; using A2 = test_allocator<int>; - using M = std::flat_map<short, int, std::less<int>, KeyContainer<short, A1>, ValueContainer<int, A2>>; + using M = std::flat_map<long, int, std::less<int>, KeyContainer<long, A1>, ValueContainer<int, A2>>; using P = std::pair<int, int>; P ar[] = {{1, 1}, {2, 2}, {4, 4}, {5, 5}}; M m = {std::sorted_unique, ar, ar + 4, {}, A1(5)}; // implicit ctor diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_key.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_key.pass.cpp index e4cce76..22638f7 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_key.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_key.pass.cpp @@ -27,7 +27,7 @@ template <class KeyContainer, class ValueContainer, class Compare = std::less<>> constexpr void test() { - using M = std::flat_map<int, char, Compare, KeyContainer, ValueContainer>; + using M = std::flat_map<int, long, Compare, KeyContainer, ValueContainer>; auto make = [](std::initializer_list<int> il) { M m; @@ -71,17 +71,17 @@ constexpr void test() { } constexpr bool test() { - test<std::vector<int>, std::vector<char>>(); - test<std::vector<int>, std::vector<char>, std::greater<>>(); + test<std::vector<int>, std::vector<long>>(); + test<std::vector<int>, std::vector<long>, std::greater<>>(); #ifndef __cpp_lib_constexpr_deque if (!TEST_IS_CONSTANT_EVALUATED) #endif { - test<std::deque<int>, std::vector<char>>(); + test<std::deque<int>, std::vector<long>>(); } - test<MinSequenceContainer<int>, MinSequenceContainer<char>>(); - test<std::vector<int, min_allocator<int>>, std::vector<char, min_allocator<char>>>(); + test<MinSequenceContainer<int>, MinSequenceContainer<long>>(); + test<std::vector<int, min_allocator<int>>, std::vector<long, min_allocator<long>>>(); if (!TEST_IS_CONSTANT_EVALUATED) { auto erase_function = [](auto& m, auto key_arg) { diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.observers/comp.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.observers/comp.pass.cpp index 5712493..626f6ad 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.observers/comp.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.observers/comp.pass.cpp @@ -35,7 +35,7 @@ constexpr bool test() { assert(kc(1, 2)); assert(!kc(2, 1)); auto vc = m.value_comp(); - ASSERT_SAME_TYPE(decltype(vc(std::make_pair(1, 2), std::make_pair(1, 2))), bool); + ASSERT_SAME_TYPE(decltype(vc(std::make_pair(1, '2'), std::make_pair(1, '2'))), bool); assert(vc({1, '2'}, {2, '1'})); assert(!vc({2, '1'}, {1, '2'})); } diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/helpers.h b/libcxx/test/std/containers/container.adaptors/flat.map/helpers.h index 932f330..445de4f 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/helpers.h +++ b/libcxx/test/std/containers/container.adaptors/flat.map/helpers.h @@ -15,6 +15,7 @@ #include <vector> #include <flat_map> #include <ranges> +#include <type_traits> #include "../flat_helpers.h" #include "test_allocator.h" diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/copy_assign.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/copy_assign.pass.cpp index fd57a10..2edfca5 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/copy_assign.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/copy_assign.pass.cpp @@ -12,6 +12,7 @@ // flat_multimap& operator=(const flat_multimap& m); +#include <cassert> #include <deque> #include <flat_map> #include <functional> @@ -28,8 +29,8 @@ constexpr void test() { // test_allocator is not propagated using C = test_less<int>; KeyContainer<int, test_allocator<int>> ks({1, 1, 3, 5}, test_allocator<int>(6)); - ValueContainer<char, test_allocator<char>> vs({2, 2, 2, 1}, test_allocator<char>(7)); - using M = std::flat_multimap<int, char, C, decltype(ks), decltype(vs)>; + ValueContainer<long, test_allocator<long>> vs({2, 2, 2, 1}, test_allocator<long>(7)); + using M = std::flat_multimap<int, long, C, decltype(ks), decltype(vs)>; auto mo = M(ks, vs, C(5)); auto m = M({{3, 3}, {4, 4}, {5, 5}, {5, 5}}, C(3), test_allocator<int>(2)); m = mo; @@ -38,23 +39,23 @@ constexpr void test() { assert(m.keys() == ks); assert(m.values() == vs); assert(m.keys().get_allocator() == test_allocator<int>(2)); - assert(m.values().get_allocator() == test_allocator<char>(2)); + assert(m.values().get_allocator() == test_allocator<long>(2)); // mo is unchanged assert(mo.key_comp() == C(5)); assert(mo.keys() == ks); assert(mo.values() == vs); assert(mo.keys().get_allocator() == test_allocator<int>(6)); - assert(mo.values().get_allocator() == test_allocator<char>(7)); + assert(mo.values().get_allocator() == test_allocator<long>(7)); } { // other_allocator is propagated using C = test_less<int>; using Ks = KeyContainer<int, other_allocator<int>>; - using Vs = ValueContainer<char, other_allocator<char>>; + using Vs = ValueContainer<long, other_allocator<long>>; auto ks = Ks({1, 1, 3, 5}, other_allocator<int>(6)); - auto vs = Vs({2, 2, 2, 1}, other_allocator<char>(7)); - using M = std::flat_multimap<int, char, C, Ks, Vs>; + auto vs = Vs({2, 2, 2, 1}, other_allocator<long>(7)); + using M = std::flat_multimap<int, long, C, Ks, Vs>; auto mo = M(Ks(ks, other_allocator<int>(6)), Vs(vs, other_allocator<int>(7)), C(5)); auto m = M({{3, 3}, {4, 4}, {5, 5}, {5, 5}}, C(3), other_allocator<int>(2)); m = mo; @@ -63,14 +64,14 @@ constexpr void test() { assert(m.keys() == ks); assert(m.values() == vs); assert(m.keys().get_allocator() == other_allocator<int>(6)); - assert(m.values().get_allocator() == other_allocator<char>(7)); + assert(m.values().get_allocator() == other_allocator<long>(7)); // mo is unchanged assert(mo.key_comp() == C(5)); assert(mo.keys() == ks); assert(mo.values() == vs); assert(mo.keys().get_allocator() == other_allocator<int>(6)); - assert(mo.values().get_allocator() == other_allocator<char>(7)); + assert(mo.values().get_allocator() == other_allocator<long>(7)); } if (!TEST_IS_CONSTANT_EVALUATED) { // comparator is copied and invariant is preserved diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct.pass.cpp index 23ef312..96f28db 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct.pass.cpp @@ -32,19 +32,19 @@ using PC = std::pair<const int, long>; void test_copy() { { - std::flat_multimap<long, short> source = {{1, 2}, {1, 3}}; + std::flat_multimap<long, int> source = {{1, 2}, {1, 3}}; std::flat_multimap s(source); ASSERT_SAME_TYPE(decltype(s), decltype(source)); assert(s == source); } { - std::flat_multimap<long, short, std::greater<long>> source = {{1, 2}, {1, 3}}; + std::flat_multimap<long, int, std::greater<long>> source = {{1, 2}, {1, 3}}; std::flat_multimap s{source}; // braces instead of parens ASSERT_SAME_TYPE(decltype(s), decltype(source)); assert(s == source); } { - std::flat_multimap<long, short, std::greater<long>> source = {{1, 2}, {1, 3}}; + std::flat_multimap<long, int, std::greater<long>> source = {{1, 2}, {1, 3}}; std::flat_multimap s(source, std::allocator<int>()); ASSERT_SAME_TYPE(decltype(s), decltype(source)); assert(s == source); @@ -53,14 +53,14 @@ void test_copy() { void test_containers() { std::deque<int, test_allocator<int>> ks({1, 2, 1, 2, 2, INT_MAX, 3}, test_allocator<int>(0, 42)); - std::deque<short, test_allocator<short>> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator<int>(0, 43)); + std::deque<long, test_allocator<long>> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator<int>(0, 43)); std::deque<int, test_allocator<int>> sorted_ks({1, 1, 2, 2, 2, 3, INT_MAX}, test_allocator<int>(0, 42)); - std::deque<short, test_allocator<short>> sorted_vs({1, 3, 2, 4, 5, 4, 3}, test_allocator<int>(0, 43)); - const std::pair<int, short> expected[] = {{1, 1}, {1, 3}, {2, 2}, {2, 4}, {2, 5}, {3, 4}, {INT_MAX, 3}}; + std::deque<long, test_allocator<long>> sorted_vs({1, 3, 2, 4, 5, 4, 3}, test_allocator<int>(0, 43)); + const std::pair<int, long> expected[] = {{1, 1}, {1, 3}, {2, 2}, {2, 4}, {2, 5}, {3, 4}, {INT_MAX, 3}}; { std::flat_multimap s(ks, vs); - ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::less<int>, decltype(ks), decltype(vs)>); + ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::less<int>, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 43); @@ -68,7 +68,7 @@ void test_containers() { { std::flat_multimap s(std::sorted_equivalent, sorted_ks, sorted_vs); - ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::less<int>, decltype(ks), decltype(vs)>); + ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::less<int>, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 43); @@ -76,7 +76,7 @@ void test_containers() { { std::flat_multimap s(ks, vs, test_allocator<long>(0, 44)); - ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::less<int>, decltype(ks), decltype(vs)>); + ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::less<int>, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 44); assert(s.values().get_allocator().get_id() == 44); @@ -84,7 +84,7 @@ void test_containers() { { std::flat_multimap s(std::sorted_equivalent, sorted_ks, sorted_vs, test_allocator<long>(0, 44)); - ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::less<int>, decltype(ks), decltype(vs)>); + ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::less<int>, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 44); assert(s.values().get_allocator().get_id() == 44); @@ -93,14 +93,14 @@ void test_containers() { void test_containers_compare() { std::deque<int, test_allocator<int>> ks({1, 2, 1, 2, 2, INT_MAX, 3}, test_allocator<int>(0, 42)); - std::deque<short, test_allocator<short>> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator<int>(0, 43)); + std::deque<long, test_allocator<long>> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator<int>(0, 43)); std::deque<int, test_allocator<int>> sorted_ks({INT_MAX, 3, 2, 2, 2, 1, 1}, test_allocator<int>(0, 42)); - std::deque<short, test_allocator<short>> sorted_vs({3, 4, 2, 4, 5, 1, 3}, test_allocator<int>(0, 43)); - const std::pair<int, short> expected[] = {{INT_MAX, 3}, {3, 4}, {2, 2}, {2, 4}, {2, 5}, {1, 1}, {1, 3}}; + std::deque<long, test_allocator<long>> sorted_vs({3, 4, 2, 4, 5, 1, 3}, test_allocator<int>(0, 43)); + const std::pair<int, long> expected[] = {{INT_MAX, 3}, {3, 4}, {2, 2}, {2, 4}, {2, 5}, {1, 1}, {1, 3}}; { std::flat_multimap s(ks, vs, std::greater<int>()); - ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::greater<int>, decltype(ks), decltype(vs)>); + ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::greater<int>, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 43); @@ -108,7 +108,7 @@ void test_containers_compare() { { std::flat_multimap s(std::sorted_equivalent, sorted_ks, sorted_vs, std::greater<int>()); - ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::greater<int>, decltype(ks), decltype(vs)>); + ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::greater<int>, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 43); @@ -116,7 +116,7 @@ void test_containers_compare() { { std::flat_multimap s(ks, vs, std::greater<int>(), test_allocator<long>(0, 44)); - ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::greater<int>, decltype(ks), decltype(vs)>); + ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::greater<int>, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 44); assert(s.values().get_allocator().get_id() == 44); @@ -125,7 +125,7 @@ void test_containers_compare() { std::flat_multimap s( std::sorted_equivalent, sorted_ks, sorted_vs, std::greater<int>(), test_allocator<long>(0, 44)); - ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::greater<int>, decltype(ks), decltype(vs)>); + ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::greater<int>, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 44); assert(s.values().get_allocator().get_id() == 44); @@ -281,11 +281,11 @@ void test_initializer_list_compare() { } void test_from_range() { - std::list<std::pair<int, short>> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}}; - const std::pair<int, short> expected[] = {{1, 1}, {1, 1}, {2, 2}, {3, 5}, {INT_MAX, 4}}; + std::list<std::pair<int, long>> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}}; + const std::pair<int, long> expected[] = {{1, 1}, {1, 1}, {2, 2}, {3, 5}, {INT_MAX, 4}}; { std::flat_multimap s(std::from_range, r); - ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::less<int>>); + ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::less<int>>); assert(std::ranges::equal(s, expected)); } { @@ -293,10 +293,10 @@ void test_from_range() { ASSERT_SAME_TYPE( decltype(s), std::flat_multimap<int, - short, + long, std::less<int>, std::vector<int, test_allocator<int>>, - std::vector<short, test_allocator<short>>>); + std::vector<long, test_allocator<long>>>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 42); @@ -304,11 +304,11 @@ void test_from_range() { } void test_from_range_compare() { - std::list<std::pair<int, short>> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}}; - const std::pair<int, short> expected[] = {{INT_MAX, 4}, {3, 5}, {2, 2}, {1, 1}, {1, 1}}; + std::list<std::pair<int, long>> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}}; + const std::pair<int, long> expected[] = {{INT_MAX, 4}, {3, 5}, {2, 2}, {1, 1}, {1, 1}}; { std::flat_multimap s(std::from_range, r, std::greater<int>()); - ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, short, std::greater<int>>); + ASSERT_SAME_TYPE(decltype(s), std::flat_multimap<int, long, std::greater<int>>); assert(std::ranges::equal(s, expected)); } { @@ -316,10 +316,10 @@ void test_from_range_compare() { ASSERT_SAME_TYPE( decltype(s), std::flat_multimap<int, - short, + long, std::greater<int>, std::vector<int, test_allocator<int>>, - std::vector<short, test_allocator<short>>>); + std::vector<long, test_allocator<long>>>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 42); diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct_pmr.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct_pmr.pass.cpp index 1955a88..d809436 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct_pmr.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct_pmr.pass.cpp @@ -32,19 +32,19 @@ using PC = std::pair<const int, long>; void test_containers() { std::deque<int, test_allocator<int>> ks({1, 2, 1, 2, 2, INT_MAX, 3}, test_allocator<int>(0, 42)); - std::deque<short, test_allocator<short>> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator<int>(0, 43)); + std::deque<long, test_allocator<long>> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator<int>(0, 43)); std::deque<int, test_allocator<int>> sorted_ks({1, 1, 2, 2, 2, 3, INT_MAX}, test_allocator<int>(0, 42)); - std::deque<short, test_allocator<short>> sorted_vs({1, 3, 2, 4, 5, 4, 3}, test_allocator<int>(0, 43)); - const std::pair<int, short> expected[] = {{1, 1}, {1, 3}, {2, 2}, {2, 4}, {2, 5}, {3, 4}, {INT_MAX, 3}}; + std::deque<long, test_allocator<long>> sorted_vs({1, 3, 2, 4, 5, 4, 3}, test_allocator<int>(0, 43)); + const std::pair<int, long> expected[] = {{1, 1}, {1, 3}, {2, 2}, {2, 4}, {2, 5}, {3, 4}, {INT_MAX, 3}}; { std::pmr::monotonic_buffer_resource mr; std::pmr::monotonic_buffer_resource mr2; std::pmr::deque<int> pks(ks.begin(), ks.end(), &mr); - std::pmr::deque<short> pvs(vs.begin(), vs.end(), &mr); + std::pmr::deque<long> pvs(vs.begin(), vs.end(), &mr); std::flat_multimap s(std::move(pks), std::move(pvs), &mr2); ASSERT_SAME_TYPE( - decltype(s), std::flat_multimap<int, short, std::less<int>, std::pmr::deque<int>, std::pmr::deque<short>>); + decltype(s), std::flat_multimap<int, long, std::less<int>, std::pmr::deque<int>, std::pmr::deque<long>>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().resource() == &mr2); assert(s.values().get_allocator().resource() == &mr2); @@ -53,11 +53,11 @@ void test_containers() { std::pmr::monotonic_buffer_resource mr; std::pmr::monotonic_buffer_resource mr2; std::pmr::deque<int> pks(sorted_ks.begin(), sorted_ks.end(), &mr); - std::pmr::deque<short> pvs(sorted_vs.begin(), sorted_vs.end(), &mr); + std::pmr::deque<long> pvs(sorted_vs.begin(), sorted_vs.end(), &mr); std::flat_multimap s(std::sorted_equivalent, std::move(pks), std::move(pvs), &mr2); ASSERT_SAME_TYPE( - decltype(s), std::flat_multimap<int, short, std::less<int>, std::pmr::deque<int>, std::pmr::deque<short>>); + decltype(s), std::flat_multimap<int, long, std::less<int>, std::pmr::deque<int>, std::pmr::deque<long>>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().resource() == &mr2); assert(s.values().get_allocator().resource() == &mr2); @@ -66,20 +66,20 @@ void test_containers() { void test_containers_compare() { std::deque<int, test_allocator<int>> ks({1, 2, 1, 2, 2, INT_MAX, 3}, test_allocator<int>(0, 42)); - std::deque<short, test_allocator<short>> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator<int>(0, 43)); + std::deque<long, test_allocator<long>> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator<int>(0, 43)); std::deque<int, test_allocator<int>> sorted_ks({INT_MAX, 3, 2, 2, 2, 1, 1}, test_allocator<int>(0, 42)); - std::deque<short, test_allocator<short>> sorted_vs({3, 4, 2, 4, 5, 1, 3}, test_allocator<int>(0, 43)); - const std::pair<int, short> expected[] = {{INT_MAX, 3}, {3, 4}, {2, 2}, {2, 4}, {2, 5}, {1, 1}, {1, 3}}; + std::deque<long, test_allocator<long>> sorted_vs({3, 4, 2, 4, 5, 1, 3}, test_allocator<int>(0, 43)); + const std::pair<int, long> expected[] = {{INT_MAX, 3}, {3, 4}, {2, 2}, {2, 4}, {2, 5}, {1, 1}, {1, 3}}; { std::pmr::monotonic_buffer_resource mr; std::pmr::monotonic_buffer_resource mr2; std::pmr::deque<int> pks(ks.begin(), ks.end(), &mr); - std::pmr::deque<short> pvs(vs.begin(), vs.end(), &mr); + std::pmr::deque<long> pvs(vs.begin(), vs.end(), &mr); std::flat_multimap s(std::move(pks), std::move(pvs), std::greater<int>(), &mr2); ASSERT_SAME_TYPE( - decltype(s), std::flat_multimap<int, short, std::greater<int>, std::pmr::deque<int>, std::pmr::deque<short>>); + decltype(s), std::flat_multimap<int, long, std::greater<int>, std::pmr::deque<int>, std::pmr::deque<long>>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().resource() == &mr2); assert(s.values().get_allocator().resource() == &mr2); @@ -88,11 +88,11 @@ void test_containers_compare() { std::pmr::monotonic_buffer_resource mr; std::pmr::monotonic_buffer_resource mr2; std::pmr::deque<int> pks(sorted_ks.begin(), sorted_ks.end(), &mr); - std::pmr::deque<short> pvs(sorted_vs.begin(), sorted_vs.end(), &mr); + std::pmr::deque<long> pvs(sorted_vs.begin(), sorted_vs.end(), &mr); std::flat_multimap s(std::sorted_equivalent, std::move(pks), std::move(pvs), std::greater<int>(), &mr2); ASSERT_SAME_TYPE( - decltype(s), std::flat_multimap<int, short, std::greater<int>, std::pmr::deque<int>, std::pmr::deque<short>>); + decltype(s), std::flat_multimap<int, long, std::greater<int>, std::pmr::deque<int>, std::pmr::deque<long>>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().resource() == &mr2); assert(s.values().get_allocator().resource() == &mr2); diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/dtor_noexcept.pass.cpp index 104d567..2534a47 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/dtor_noexcept.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/dtor_noexcept.pass.cpp @@ -16,6 +16,7 @@ #include <deque> #include <flat_map> #include <functional> +#include <type_traits> #include <vector> #include "test_macros.h" diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/initializer_list.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/initializer_list.pass.cpp index e40708a..418b46bc 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/initializer_list.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/initializer_list.pass.cpp @@ -38,24 +38,24 @@ struct DefaultCtableComp { template <template <class...> class KeyContainer, template <class...> class ValueContainer> constexpr void test() { - std::pair<int, short> expected[] = {{1, 1}, {2, 2}, {2, 2}, {3, 3}, {3, 3}, {5, 2}}; + std::pair<int, long> expected[] = {{1, 1}, {2, 2}, {2, 2}, {3, 3}, {3, 3}, {5, 2}}; { // flat_multimap(initializer_list<value_type>); - using M = std::flat_multimap<int, short>; - std::initializer_list<std::pair<int, short>> il = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}; + using M = std::flat_multimap<int, long>; + std::initializer_list<std::pair<int, long>> il = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}; M m(il); assert(std::ranges::equal(m, expected)); } { // flat_multimap(initializer_list<value_type>); // explicit(false) - using M = std::flat_multimap<int, short>; + using M = std::flat_multimap<int, long>; M m = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}; assert(std::ranges::equal(m, expected)); } { // flat_multimap(initializer_list<value_type>); - using M = std::flat_multimap<int, short, std::greater<int>, KeyContainer<int, min_allocator<int>>>; + using M = std::flat_multimap<int, long, std::greater<int>, KeyContainer<int, min_allocator<int>>>; M m = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}; assert(std::equal(m.rbegin(), m.rend(), expected, expected + 6)); } @@ -80,7 +80,7 @@ constexpr void test() { { // flat_multimap(initializer_list<value_type>, const key_compare&); using C = test_less<int>; - using M = std::flat_multimap<int, short, C>; + using M = std::flat_multimap<int, long, C>; auto m = M({{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}, C(10)); assert(std::equal(m.begin(), m.end(), expected, expected + 6)); assert(m.key_comp() == C(10)); @@ -93,7 +93,7 @@ constexpr void test() { if (!TEST_IS_CONSTANT_EVALUATED) { // flat_multimap(initializer_list<value_type>, const key_compare&); // Sorting uses the comparator that was passed in - using M = std::flat_multimap<int, short, std::function<bool(int, int)>, KeyContainer<int, min_allocator<int>>>; + using M = std::flat_multimap<int, long, std::function<bool(int, int)>, KeyContainer<int, min_allocator<int>>>; auto m = M({{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}, std::greater<int>()); assert(std::equal(m.rbegin(), m.rend(), expected, expected + 6)); assert(m.key_comp()(2, 1) == true); diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/iter_iter.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/iter_iter.pass.cpp index c7f2d16..46c8922 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/iter_iter.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/iter_iter.pass.cpp @@ -119,19 +119,19 @@ constexpr void test() { template <template <class...> class KeyContainer, template <class...> class ValueContainer> constexpr void test_alloc() { - using P = std::pair<int, short>; + using P = std::pair<int, long>; P ar[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7}, {3, 8}, {3, 9}}; { // flat_multimap(InputIterator , InputIterator, const Allocator&) using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_multimap<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>; auto m = M(ar, ar + 9, A1(5)); assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 1, 1, 2, 2, 2, 3, 3, 3})); check_possible_values( m.values(), - std::vector<std::vector<short>>{ + std::vector<std::vector<long>>{ {1, 2, 3}, {1, 2, 3}, {1, 2, 3}, @@ -149,13 +149,13 @@ constexpr void test_alloc() { // flat_multimap(InputIterator , InputIterator, const Allocator&) // explicit(false) using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_multimap<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>; M m = {ar, ar + 9, A1(5)}; // implicit ctor assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 1, 1, 2, 2, 2, 3, 3, 3})); check_possible_values( m.values(), - std::vector<std::vector<short>>{ + std::vector<std::vector<long>>{ {1, 2, 3}, {1, 2, 3}, {1, 2, 3}, @@ -173,13 +173,13 @@ constexpr void test_alloc() { // flat_multimap(InputIterator , InputIterator, const key_compare&, const Allocator&) using C = test_less<int>; using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_multimap<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_multimap<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>; auto m = M(ar, ar + 9, C(3), A1(5)); assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 1, 1, 2, 2, 2, 3, 3, 3})); check_possible_values( m.values(), - std::vector<std::vector<short>>{ + std::vector<std::vector<long>>{ {1, 2, 3}, {1, 2, 3}, {1, 2, 3}, @@ -198,13 +198,13 @@ constexpr void test_alloc() { // flat_multimap(InputIterator , InputIterator, const key_compare&, const Allocator&) // explicit(false) using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_multimap<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>; M m = {ar, ar + 9, {}, A2(5)}; // implicit ctor assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 1, 1, 2, 2, 2, 3, 3, 3})); check_possible_values( m.values(), - std::vector<std::vector<short>>{ + std::vector<std::vector<long>>{ {1, 2, 3}, {1, 2, 3}, {1, 2, 3}, diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/move_assign.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/move_assign.pass.cpp index 292bb5c..bf7b34c 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/move_assign.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/move_assign.pass.cpp @@ -31,8 +31,8 @@ constexpr void test() { { using C = test_less<int>; using A1 = test_allocator<int>; - using A2 = test_allocator<char>; - using M = std::flat_multimap<int, char, C, KeyContainer<int, A1>, ValueContainer<char, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_multimap<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>; M mo = M({{1, 1}, {1, 3}, {3, 2}}, C(5), A1(7)); M m = M({}, C(3), A1(7)); m = std::move(mo); @@ -46,8 +46,8 @@ constexpr void test() { { using C = test_less<int>; using A1 = other_allocator<int>; - using A2 = other_allocator<char>; - using M = std::flat_multimap<int, char, C, KeyContainer<int, A1>, ValueContainer<char, A2>>; + using A2 = other_allocator<long>; + using M = std::flat_multimap<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>; M mo = M({{4, 5}, {4, 4}}, C(5), A1(7)); M m = M({{1, 1}, {2, 2}, {3, 3}, {4, 4}}, C(3), A1(7)); m = std::move(mo); diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/pmr.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/pmr.pass.cpp index 8b518f6..67b147f 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/pmr.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/pmr.pass.cpp @@ -166,12 +166,12 @@ int main(int, char**) { } { // flat_multimap(InputIterator first, InputIterator last, const Allocator& a); - using P = std::pair<int, short>; + using P = std::pair<int, long>; P ar[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7}, {3, 8}, {3, 9}}; P expected[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {2, 7}, {3, 6}, {3, 8}, {3, 9}}; { // cpp17 iterator - using M = std::flat_multimap<int, short, std::less<int>, std::pmr::vector<int>, std::pmr::vector<short>>; + using M = std::flat_multimap<int, long, std::less<int>, std::pmr::vector<int>, std::pmr::vector<long>>; std::pmr::monotonic_buffer_resource mr; std::pmr::vector<M> vm(&mr); vm.emplace_back(cpp17_input_iterator<const P*>(ar), cpp17_input_iterator<const P*>(ar + 9)); @@ -181,7 +181,7 @@ int main(int, char**) { assert(vm[0].values().get_allocator().resource() == &mr); } { - using M = std::flat_multimap<int, short, std::less<int>, std::pmr::vector<int>, std::pmr::vector<short>>; + using M = std::flat_multimap<int, long, std::less<int>, std::pmr::vector<int>, std::pmr::vector<long>>; std::pmr::monotonic_buffer_resource mr; std::pmr::vector<M> vm(&mr); vm.emplace_back(ar, ar); @@ -242,12 +242,12 @@ int main(int, char**) { } { // flat_multimap(from_range_t, R&&, const Alloc&); - using P = std::pair<int, short>; + using P = std::pair<int, long>; P ar[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7}, {3, 8}, {3, 9}}; P expected[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {2, 7}, {3, 6}, {3, 8}, {3, 9}}; { // input_range - using M = std::flat_multimap<int, short, std::less<int>, std::pmr::vector<int>, std::pmr::vector<short>>; + using M = std::flat_multimap<int, long, std::less<int>, std::pmr::vector<int>, std::pmr::vector<long>>; using Iter = cpp20_input_iterator<const P*>; using Sent = sentinel_wrapper<Iter>; using R = std::ranges::subrange<Iter, Sent>; @@ -260,7 +260,7 @@ int main(int, char**) { assert(vm[0].values().get_allocator().resource() == &mr); } { - using M = std::flat_multimap<int, short, std::less<int>, std::pmr::vector<int>, std::pmr::vector<short>>; + using M = std::flat_multimap<int, long, std::less<int>, std::pmr::vector<int>, std::pmr::vector<long>>; using R = std::ranges::subrange<const P*>; std::pmr::monotonic_buffer_resource mr; std::pmr::vector<M> vm(&mr); diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/range.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/range.pass.cpp index 0b36551..fad2cae 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/range.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/range.pass.cpp @@ -176,19 +176,19 @@ constexpr void test() { template <template <class...> class KeyContainer, template <class...> class ValueContainer> constexpr void test_alloc() { - using P = std::pair<int, short>; + using P = std::pair<int, long>; P ar[] = {{1, 1}, {1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7}, {3, 8}, {3, 9}}; { // flat_multimap(from_range_t, R&&, const Allocator&) using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_multimap<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>; using R = std::ranges::subrange<const P*>; auto m = M(std::from_range, R(ar, ar + 9), A1(5)); assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 1, 1, 2, 2, 2, 3, 3, 3})); check_possible_values( m.values(), - std::vector<std::vector<short>>{ + std::vector<std::vector<long>>{ {1, 2, 3}, {1, 2, 3}, {1, 2, 3}, @@ -206,14 +206,14 @@ constexpr void test_alloc() { // flat_multimap(from_range_t, R&&, const Allocator&) // explicit(false) using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_multimap<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>; using R = std::ranges::subrange<const P*>; M m = {std::from_range, R(ar, ar + 9), A1(5)}; // implicit ctor assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 1, 1, 2, 2, 2, 3, 3, 3})); check_possible_values( m.values(), - std::vector<std::vector<short>>{ + std::vector<std::vector<long>>{ {1, 2, 3}, {1, 2, 3}, {1, 2, 3}, @@ -231,14 +231,14 @@ constexpr void test_alloc() { // flat_multimap(from_range_t, R&&, const key_compare&, const Allocator&) using C = test_less<int>; using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_multimap<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_multimap<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>; using R = std::ranges::subrange<const P*>; auto m = M(std::from_range, R(ar, ar + 9), C(3), A1(5)); assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 1, 1, 2, 2, 2, 3, 3, 3})); check_possible_values( m.values(), - std::vector<std::vector<short>>{ + std::vector<std::vector<long>>{ {1, 2, 3}, {1, 2, 3}, {1, 2, 3}, @@ -257,14 +257,14 @@ constexpr void test_alloc() { // flat_multimap(from_range_t, R&&, const key_compare&, const Allocator&) // explicit(false) using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_multimap<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>; using R = std::ranges::subrange<const P*>; M m = {std::from_range, R(ar, ar + 9), {}, A2(5)}; // implicit ctor assert(std::ranges::equal(m.keys(), KeyContainer<int, A1>{1, 1, 1, 2, 2, 2, 3, 3, 3})); check_possible_values( m.values(), - std::vector<std::vector<short>>{ + std::vector<std::vector<long>>{ {1, 2, 3}, {1, 2, 3}, {1, 2, 3}, diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_container.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_container.pass.cpp index b07f8ba..b9f491a 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_container.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_container.pass.cpp @@ -39,18 +39,18 @@ template <template <class...> class KeyContainer, template <class...> class Valu constexpr void test() { { // flat_multimap(sorted_equivalent_t, key_container_type , mapped_container_type) - using M = std::flat_multimap<int, char, std::less<int>, KeyContainer<int>, ValueContainer<char>>; + using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int>, ValueContainer<long>>; KeyContainer<int> ks = {1, 4, 4, 10}; - ValueContainer<char> vs = {4, 3, 2, 1}; + ValueContainer<long> vs = {4, 3, 2, 1}; auto ks2 = ks; auto vs2 = vs; auto m = M(std::sorted_equivalent, ks, vs); - assert(std::ranges::equal(m, std::vector<std::pair<int, char>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}})); + assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}})); m = M(std::sorted_equivalent, std::move(ks), std::move(vs)); assert(ks.empty()); // it was moved-from assert(vs.empty()); // it was moved-from - assert(std::ranges::equal(m, std::vector<std::pair<int, char>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}})); + assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}})); // explicit(false) M m2 = {std::sorted_equivalent, std::move(ks2), std::move(vs2)}; @@ -60,16 +60,16 @@ constexpr void test() { // flat_multimap(sorted_equivalent_t, key_container_type , mapped_container_type) // non-default container, comparator and allocator type using Ks = KeyContainer<int, min_allocator<int>>; - using Vs = ValueContainer<char, min_allocator<char>>; - using M = std::flat_multimap<int, char, std::greater<int>, Ks, Vs>; + using Vs = ValueContainer<long, min_allocator<long>>; + using M = std::flat_multimap<int, long, std::greater<int>, Ks, Vs>; Ks ks = {10, 4, 4, 1}; Vs vs = {1, 2, 3, 4}; auto m = M(std::sorted_equivalent, ks, vs); - assert(std::ranges::equal(m, std::vector<std::pair<int, char>>{{10, 1}, {4, 2}, {4, 3}, {1, 4}})); + assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{10, 1}, {4, 2}, {4, 3}, {1, 4}})); m = M(std::sorted_equivalent, std::move(ks), std::move(vs)); assert(ks.empty()); // it was moved-from assert(vs.empty()); // it was moved-from - assert(std::ranges::equal(m, std::vector<std::pair<int, char>>{{10, 1}, {4, 2}, {4, 3}, {1, 4}})); + assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{10, 1}, {4, 2}, {4, 3}, {1, 4}})); } { // flat_multimap(sorted_equivalent_t, key_container_type , mapped_container_type) @@ -81,19 +81,19 @@ constexpr void test() { auto m = M(std::sorted_equivalent, std::move(ks), std::move(vs)); assert(ks.empty()); // it was moved-from assert(vs.empty()); // it was moved-from - assert(std::ranges::equal(m, std::vector<std::pair<int, char>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}})); + assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}})); assert(m.keys().get_allocator() == A(4)); assert(m.values().get_allocator() == A(5)); } { // flat_multimap(sorted_equivalent_t, key_container_type , mapped_container_type, key_compare) using C = test_less<int>; - using M = std::flat_multimap<int, char, C, KeyContainer<int>, ValueContainer<char>>; + using M = std::flat_multimap<int, long, C, KeyContainer<int>, ValueContainer<long>>; KeyContainer<int> ks = {1, 4, 4, 10}; - ValueContainer<char> vs = {4, 3, 2, 1}; + ValueContainer<long> vs = {4, 3, 2, 1}; auto m = M(std::sorted_equivalent, ks, vs, C(4)); - assert(std::ranges::equal(m, std::vector<std::pair<int, char>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}})); + assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}})); assert(m.key_comp() == C(4)); // explicit(false) @@ -109,7 +109,7 @@ constexpr void test() { KeyContainer<int, A> ks = {1, 4, 4, 10}; ValueContainer<int, A> vs = {4, 3, 2, 1}; auto m = M(std::sorted_equivalent, ks, vs, C(4), A(5)); - assert(std::ranges::equal(m, std::vector<std::pair<int, char>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}})); + assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}})); assert(m.key_comp() == C(4)); assert(m.keys().get_allocator() == A(5)); assert(m.values().get_allocator() == A(5)); @@ -130,7 +130,7 @@ constexpr void test() { auto m = M(std::sorted_equivalent, ks, vs, A(6)); // replaces the allocators assert(!ks.empty()); // it was an lvalue above assert(!vs.empty()); // it was an lvalue above - assert(std::ranges::equal(m, std::vector<std::pair<int, char>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}})); + assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{1, 4}, {4, 3}, {4, 2}, {10, 1}})); assert(m.keys().get_allocator() == A(6)); assert(m.values().get_allocator() == A(6)); diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_initializer_list.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_initializer_list.pass.cpp index 555b8d4..4245919 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_initializer_list.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_initializer_list.pass.cpp @@ -36,8 +36,8 @@ template <class T, class U> constexpr std::initializer_list<std::pair<T, U>> il = {{1, 4}, {4, 2}, {4, 4}, {5, 5}}; constexpr auto il1 = il<int, int>; -constexpr auto il2 = il<int, short>; -constexpr auto il3 = il<short, int>; +constexpr auto il2 = il<int, long>; +constexpr auto il3 = il<long, int>; template <template <class...> class KeyContainer, template <class...> class ValueContainer> constexpr void test() { @@ -74,10 +74,10 @@ constexpr void test() { { // flat_multimap(sorted_equivalent_t, initializer_list<value_type>, const Allocator&) using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_multimap<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>; auto m = M(std::sorted_equivalent, il2, A1(5)); - assert(std::ranges::equal(m, std::vector<std::pair<int, short>>{{1, 4}, {4, 2}, {4, 4}, {5, 5}})); + assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{1, 4}, {4, 2}, {4, 4}, {5, 5}})); assert(m.keys().get_allocator() == A1(5)); assert(m.values().get_allocator() == A2(5)); @@ -91,10 +91,10 @@ constexpr void test() { // flat_multimap(sorted_equivalent_t, initializer_list<value_type>, const key_compare&, const Allocator&); using C = test_less<int>; using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_multimap<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_multimap<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>; auto m = M(std::sorted_equivalent, il2, C(3), A1(5)); - assert(std::ranges::equal(m, std::vector<std::pair<int, short>>{{1, 4}, {4, 2}, {4, 4}, {5, 5}})); + assert(std::ranges::equal(m, std::vector<std::pair<int, long>>{{1, 4}, {4, 2}, {4, 4}, {5, 5}})); assert(m.key_comp() == C(3)); assert(m.keys().get_allocator() == A1(5)); assert(m.values().get_allocator() == A2(5)); @@ -102,11 +102,11 @@ constexpr void test() { { // flat_multimap(sorted_equivalent_t, initializer_list<value_type>, const key_compare&, const Allocator&); // explicit(false) - using A1 = test_allocator<short>; + using A1 = test_allocator<long>; using A2 = test_allocator<int>; - using M = std::flat_multimap<short, int, std::less<int>, KeyContainer<short, A1>, ValueContainer<int, A2>>; + using M = std::flat_multimap<long, int, std::less<int>, KeyContainer<long, A1>, ValueContainer<int, A2>>; M m = {std::sorted_equivalent, il3, {}, A1(5)}; // implicit ctor - assert(std::ranges::equal(m, std::vector<std::pair<short, int>>{{1, 4}, {4, 2}, {4, 4}, {5, 5}})); + assert(std::ranges::equal(m, std::vector<std::pair<long, int>>{{1, 4}, {4, 2}, {4, 4}, {5, 5}})); assert(m.keys().get_allocator() == A1(5)); assert(m.values().get_allocator() == A2(5)); } diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_iter_iter.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_iter_iter.pass.cpp index 72e9695..13e8f27 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_iter_iter.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/sorted_iter_iter.pass.cpp @@ -68,7 +68,7 @@ constexpr void test() { auto m = M(std::sorted_equivalent, cpp17_input_iterator<const P*>(ar), cpp17_input_iterator<const P*>(ar + 4), - std::less<int>()); + std::less<Value>()); assert(std::ranges::equal(m, std::vector<std::pair<int, int>>{{1, 1}, {4, 2}, {4, 4}, {5, 5}})); assert(m.key_comp()(1, 2) == true); @@ -76,19 +76,19 @@ constexpr void test() { M m2 = {std::sorted_equivalent, cpp17_input_iterator<const P*>(ar), cpp17_input_iterator<const P*>(ar + 4), - std::less<int>()}; + std::less<Value>()}; assert(m2 == m); } { // flat_multimap(sorted_equivalent_t, InputIterator, InputIterator, const key_compare&); // greater - using M = std::flat_multimap<Key, Value, std::greater<int>, KeyContainer, ValueContainer>; + using M = std::flat_multimap<Key, Value, std::greater<Value>, KeyContainer, ValueContainer>; using P = std::pair<Key, Value>; P ar[] = {{5, 5}, {4, 4}, {4, 2}, {1, 1}}; auto m = M(std::sorted_equivalent, cpp17_input_iterator<const P*>(ar), cpp17_input_iterator<const P*>(ar + 4), - std::greater<int>()); + std::greater<Value>()); assert(std::ranges::equal(m, std::vector<std::pair<int, int>>{{5, 5}, {4, 4}, {4, 2}, {1, 1}})); } { @@ -108,8 +108,8 @@ constexpr void test_alloc() { { // flat_multimap(sorted_equivalent_t, InputIterator , InputIterator, const Allocator&) using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_multimap<int, short, std::less<int>, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_multimap<int, long, std::less<int>, KeyContainer<int, A1>, ValueContainer<long, A2>>; using P = std::pair<int, int>; P ar[] = {{1, 1}, {4, 2}, {4, 4}, {5, 5}}; auto m = M(std::sorted_equivalent, ar, ar + 4, A1(5)); @@ -127,8 +127,8 @@ constexpr void test_alloc() { // flat_multimap(sorted_equivalent_t, InputIterator, InputIterator, const key_compare&, const Allocator&); using C = test_less<int>; using A1 = test_allocator<int>; - using A2 = test_allocator<short>; - using M = std::flat_multimap<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>>; + using A2 = test_allocator<long>; + using M = std::flat_multimap<int, long, C, KeyContainer<int, A1>, ValueContainer<long, A2>>; using P = std::pair<int, int>; P ar[] = {{1, 1}, {4, 2}, {4, 4}, {5, 5}}; auto m = M(std::sorted_equivalent, ar, ar + 4, C(3), A1(5)); @@ -140,9 +140,9 @@ constexpr void test_alloc() { { // flat_multimap(sorted_equivalent_t, InputIterator, InputIterator, const key_compare&, const Allocator&); // explicit(false) - using A1 = test_allocator<short>; + using A1 = test_allocator<long>; using A2 = test_allocator<int>; - using M = std::flat_multimap<short, int, std::less<int>, KeyContainer<short, A1>, ValueContainer<int, A2>>; + using M = std::flat_multimap<long, int, std::less<int>, KeyContainer<long, A1>, ValueContainer<int, A2>>; using P = std::pair<int, int>; P ar[] = {{1, 1}, {4, 2}, {4, 4}, {5, 5}}; M m = {std::sorted_equivalent, ar, ar + 4, {}, A1(5)}; // implicit ctor diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/erase_key.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/erase_key.pass.cpp index d267c55..36fb34c 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/erase_key.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/erase_key.pass.cpp @@ -29,7 +29,7 @@ template <class KeyContainer, class ValueContainer, class Compare = std::less<>> constexpr void test() { - using M = std::flat_multimap<int, char, Compare, KeyContainer, ValueContainer>; + using M = std::flat_multimap<int, long, Compare, KeyContainer, ValueContainer>; auto make = [](std::initializer_list<int> il) { M m; @@ -79,14 +79,14 @@ constexpr void test() { } constexpr bool test() { - test<std::vector<int>, std::vector<char>>(); - test<std::vector<int>, std::vector<char>, std::greater<>>(); + test<std::vector<int>, std::vector<long>>(); + test<std::vector<int>, std::vector<long>, std::greater<>>(); #ifndef __cpp_lib_constexpr_deque if (!TEST_IS_CONSTANT_EVALUATED) #endif - test<std::deque<int>, std::vector<char>>(); - test<MinSequenceContainer<int>, MinSequenceContainer<char>>(); - test<std::vector<int, min_allocator<int>>, std::vector<char, min_allocator<char>>>(); + test<std::deque<int>, std::vector<long>>(); + test<MinSequenceContainer<int>, MinSequenceContainer<long>>(); + test<std::vector<int, min_allocator<int>>, std::vector<long, min_allocator<long>>>(); if (!TEST_IS_CONSTANT_EVALUATED) { auto erase_function = [](auto& m, auto key_arg) { diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.observers/comp.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.observers/comp.pass.cpp index 070fbb0..2b52b47 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.observers/comp.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.observers/comp.pass.cpp @@ -36,7 +36,7 @@ constexpr bool test() { assert(kc(1, 2)); assert(!kc(2, 1)); auto vc = m.value_comp(); - ASSERT_SAME_TYPE(decltype(vc(std::make_pair(1, 2), std::make_pair(1, 2))), bool); + ASSERT_SAME_TYPE(decltype(vc(std::make_pair(1, '2'), std::make_pair(1, '2'))), bool); assert(vc({1, '2'}, {2, '1'})); assert(!vc({2, '1'}, {1, '2'})); } diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/helpers.h b/libcxx/test/std/containers/container.adaptors/flat.multimap/helpers.h index f3edd3b..ccb3218 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/helpers.h +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/helpers.h @@ -15,6 +15,7 @@ #include <vector> #include <flat_map> #include <ranges> +#include <type_traits> #include "../flat_helpers.h" #include "test_allocator.h" diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/compare.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/compare.pass.cpp index 43ebea7..81f9bbc 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/compare.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/compare.pass.cpp @@ -14,6 +14,7 @@ // template <class Alloc> // flat_multiset(const key_compare& comp, const Alloc& a); +#include <cassert> #include <deque> #include <flat_set> #include <functional> diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/copy_assign.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/copy_assign.pass.cpp index 2e63a00..de297f1 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/copy_assign.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/copy_assign.pass.cpp @@ -13,9 +13,11 @@ // flat_multiset& operator=(const flat_multiset& m); #include <algorithm> +#include <cassert> #include <deque> #include <flat_set> #include <functional> +#include <utility> #include <vector> #include "operator_hijacker.h" diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/dtor_noexcept.pass.cpp index f7243fa..0df0667 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/dtor_noexcept.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/dtor_noexcept.pass.cpp @@ -16,6 +16,7 @@ #include <deque> #include <flat_set> #include <functional> +#include <type_traits> #include <vector> #include "test_macros.h" diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move.pass.cpp index 7fb0c0e..064baa9 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move.pass.cpp @@ -145,7 +145,6 @@ void test_move_noexcept() { C c; C d = std::move(c); } -#endif // _LIBCPP_VERSION { // Comparator fails to be nothrow-move-constructible using C = std::flat_multiset<int, ThrowingMoveComp>; @@ -153,6 +152,7 @@ void test_move_noexcept() { C c; C d = std::move(c); } +#endif // _LIBCPP_VERSION } #if !defined(TEST_HAS_NO_EXCEPTIONS) diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move_assign.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move_assign.pass.cpp index 62e2181..30c06d2 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move_assign.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move_assign.pass.cpp @@ -156,7 +156,7 @@ void test_move_assign_no_except() { // This tests a conforming extension { - using C = std::flat_multiset<int, int>; + using C [[maybe_unused]] = std::flat_multiset<int, int>; LIBCPP_STATIC_ASSERT(std::is_nothrow_move_assignable_v<C>); } { @@ -168,16 +168,17 @@ void test_move_assign_no_except() { static_assert(!std::is_nothrow_move_assignable_v<C>); } { - using C = std::flat_multiset<MoveOnly, std::less<MoveOnly>, std::vector<MoveOnly, other_allocator<MoveOnly>>>; + using C [[maybe_unused]] = + std::flat_multiset<MoveOnly, std::less<MoveOnly>, std::vector<MoveOnly, other_allocator<MoveOnly>>>; LIBCPP_STATIC_ASSERT(std::is_nothrow_move_assignable_v<C>); } { - using C = std::flat_multiset<int, std::less<int>, std::vector<int, other_allocator<int>>>; + using C [[maybe_unused]] = std::flat_multiset<int, std::less<int>, std::vector<int, other_allocator<int>>>; LIBCPP_STATIC_ASSERT(std::is_nothrow_move_assignable_v<C>); } { // Test with a comparator that throws on move-assignment. - using C = std::flat_multiset<int, MoveThrowsComp>; + using C [[maybe_unused]] = std::flat_multiset<int, MoveThrowsComp>; LIBCPP_STATIC_ASSERT(!std::is_nothrow_move_assignable_v<C>); } { diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/sorted_iter_iter.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/sorted_iter_iter.pass.cpp index a3c9981..af2a51a 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/sorted_iter_iter.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/sorted_iter_iter.pass.cpp @@ -147,8 +147,8 @@ constexpr void test() { { // flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, const key_compare&, const Allocator&); // explicit(false) - using A1 = test_allocator<short>; - using M = std::flat_multiset<short, std::less<int>, KeyContainer<short, A1>>; + using A1 = test_allocator<long>; + using M = std::flat_multiset<long, std::less<int>, KeyContainer<long, A1>>; int ar[] = {1, 2, 4, 4, 5}; M m = {std::sorted_equivalent, ar, ar + 5, {}, A1(5)}; // implicit ctor assert((m == M{1, 2, 4, 4, 5})); diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/iterator.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/iterator.pass.cpp index 878b2b2..ed63897 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/iterator.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/iterator.pass.cpp @@ -57,7 +57,7 @@ constexpr void test_one() { i = m.begin(); // move-assignment typename M::const_iterator k = i; // converting constructor assert(i == k); // comparison - for (int j = 0; j < 9; ++j, ++i) { // pre-increment + for (int j = 0; j < 9; ++j, (void)++i) { // pre-increment assert(*i == expected[j]); // operator* } assert(i == m.end()); diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/copy_assign.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/copy_assign.pass.cpp index 59caa9c..33fe457 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/copy_assign.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/copy_assign.pass.cpp @@ -13,6 +13,7 @@ // flat_set& operator=(const flat_set& m); #include <algorithm> +#include <cassert> #include <deque> #include <flat_set> #include <functional> diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/dtor_noexcept.pass.cpp index 810b13b..1caf58f 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/dtor_noexcept.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/dtor_noexcept.pass.cpp @@ -16,6 +16,7 @@ #include <deque> #include <flat_set> #include <functional> +#include <type_traits> #include <vector> #include "test_macros.h" diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp index fcc15ed..b737a5f 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp @@ -123,7 +123,6 @@ constexpr void test_move_noexcept() { C c; C d = std::move(c); } -#endif // _LIBCPP_VERSION { // Comparator fails to be nothrow-move-constructible using C = std::flat_set<int, ThrowingMoveComp, KeyContainer<int>>; @@ -131,6 +130,7 @@ constexpr void test_move_noexcept() { C c; C d = std::move(c); } +#endif // _LIBCPP_VERSION } constexpr bool test() { diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move_assign.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move_assign.pass.cpp index 1c3affe..e596a67 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move_assign.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move_assign.pass.cpp @@ -159,7 +159,7 @@ void test_move_assign_no_except() { // This tests a conforming extension { - using C = std::flat_set<int, int>; + using C [[maybe_unused]] = std::flat_set<int, int>; LIBCPP_STATIC_ASSERT(std::is_nothrow_move_assignable_v<C>); } { @@ -171,16 +171,17 @@ void test_move_assign_no_except() { static_assert(!std::is_nothrow_move_assignable_v<C>); } { - using C = std::flat_set<MoveOnly, std::less<MoveOnly>, std::vector<MoveOnly, other_allocator<MoveOnly>>>; + using C [[maybe_unused]] = + std::flat_set<MoveOnly, std::less<MoveOnly>, std::vector<MoveOnly, other_allocator<MoveOnly>>>; LIBCPP_STATIC_ASSERT(std::is_nothrow_move_assignable_v<C>); } { - using C = std::flat_set<int, std::less<int>, std::vector<int, other_allocator<int>>>; + using C [[maybe_unused]] = std::flat_set<int, std::less<int>, std::vector<int, other_allocator<int>>>; LIBCPP_STATIC_ASSERT(std::is_nothrow_move_assignable_v<C>); } { // Test with a comparator that throws on move-assignment. - using C = std::flat_set<int, MoveThrowsComp>; + using C [[maybe_unused]] = std::flat_set<int, MoveThrowsComp>; LIBCPP_STATIC_ASSERT(!std::is_nothrow_move_assignable_v<C>); } { diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/sorted_iter_iter.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/sorted_iter_iter.pass.cpp index 7ffb09e..2550ed2 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/sorted_iter_iter.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/sorted_iter_iter.pass.cpp @@ -128,8 +128,8 @@ constexpr void test_alloc() { { // flat_set(sorted_unique_t, InputIterator, InputIterator, const key_compare&, const Allocator&); // explicit(false) - using A1 = test_allocator<short>; - using M = std::flat_set<short, std::less<int>, KeyContainer<short, A1>>; + using A1 = test_allocator<long>; + using M = std::flat_set<long, std::less<int>, KeyContainer<long, A1>>; int ar[] = {1, 2, 4, 5}; M m = {std::sorted_unique, ar, ar + 4, {}, A1(5)}; // implicit ctor assert((m == M{1, 2, 4, 5})); diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.iterators/iterator.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.iterators/iterator.pass.cpp index 8aafa97..d79a1db 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.iterators/iterator.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.iterators/iterator.pass.cpp @@ -56,7 +56,7 @@ constexpr void test_one() { i = m.begin(); // move-assignment typename M::const_iterator k = i; // converting constructor assert(i == k); // comparison - for (int j = 1; j <= 4; ++j, ++i) { // pre-increment + for (int j = 1; j <= 4; ++j, (void)++i) { // pre-increment assert(*i == j); // operator* } assert(i == m.end()); diff --git a/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_iterators.pass.cpp b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_iterators.pass.cpp index 5981f91..afd5a63 100644 --- a/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_iterators.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_iterators.pass.cpp @@ -15,6 +15,7 @@ #include <cassert> #include <stack> +#include <type_traits> #include "test_allocator.h" diff --git a/libcxx/test/std/containers/container.requirements/container.requirements.general/allocator_move.pass.cpp b/libcxx/test/std/containers/container.requirements/container.requirements.general/allocator_move.pass.cpp index 5de5579..e927bfc 100644 --- a/libcxx/test/std/containers/container.requirements/container.requirements.general/allocator_move.pass.cpp +++ b/libcxx/test/std/containers/container.requirements/container.requirements.general/allocator_move.pass.cpp @@ -13,6 +13,7 @@ // belonging to the container being moved. Such move construction of the // allocator shall not exit via an exception. +#include <cassert> #include <vector> #include <deque> #include <list> diff --git a/libcxx/test/std/containers/sequences/array/array.creation/to_array.verify.cpp b/libcxx/test/std/containers/sequences/array/array.creation/to_array.verify.cpp index e3efef98..ee8d8e6 100644 --- a/libcxx/test/std/containers/sequences/array/array.creation/to_array.verify.cpp +++ b/libcxx/test/std/containers/sequences/array/array.creation/to_array.verify.cpp @@ -22,21 +22,21 @@ int main(int, char**) { // expected-error@array:* {{to_array does not accept multidimensional arrays}} // expected-error@array:* {{to_array requires copy constructible elements}} // expected-error@array:* 3 {{cannot initialize}} - std::to_array(source); // expected-note {{requested here}} + (void)std::to_array(source); // expected-note {{requested here}} } { MoveOnly mo[] = {MoveOnly{3}}; // expected-error@array:* {{to_array requires copy constructible elements}} // expected-error-re@array:* 1-2{{{{(call to implicitly-deleted copy constructor of 'MoveOnly')|(call to deleted constructor of 'MoveOnly')}}}} - std::to_array(mo); // expected-note {{requested here}} + (void)std::to_array(mo); // expected-note {{requested here}} } { const MoveOnly cmo[] = {MoveOnly{3}}; // expected-error@array:* {{to_array requires move constructible elements}} // expected-error-re@array:* 0-1{{{{(call to implicitly-deleted copy constructor of 'MoveOnly')|(call to deleted constructor of 'MoveOnly')}}}} - std::to_array(std::move(cmo)); // expected-note {{requested here}} + (void)std::to_array(std::move(cmo)); // expected-note {{requested here}} } return 0; diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/dtor_noexcept.pass.cpp index f0a8394..338a0fa 100644 --- a/libcxx/test/std/containers/sequences/deque/deque.cons/dtor_noexcept.pass.cpp +++ b/libcxx/test/std/containers/sequences/deque/deque.cons/dtor_noexcept.pass.cpp @@ -12,8 +12,9 @@ // UNSUPPORTED: c++03 -#include <deque> #include <cassert> +#include <deque> +#include <type_traits> #include "test_macros.h" #include "MoveOnly.h" diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/dtor_noexcept.pass.cpp index 64c60af..8d474cf 100644 --- a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/dtor_noexcept.pass.cpp +++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/dtor_noexcept.pass.cpp @@ -12,8 +12,9 @@ // UNSUPPORTED: c++03 -#include <forward_list> #include <cassert> +#include <forward_list> +#include <type_traits> #include "test_macros.h" #include "MoveOnly.h" diff --git a/libcxx/test/std/containers/sequences/list/list.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/dtor_noexcept.pass.cpp index 44e6ddd..4ebe19f 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/dtor_noexcept.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/dtor_noexcept.pass.cpp @@ -12,8 +12,9 @@ // UNSUPPORTED: c++03 -#include <list> #include <cassert> +#include <list> +#include <type_traits> #include "test_macros.h" #include "MoveOnly.h" diff --git a/libcxx/test/std/containers/sequences/vector.bool/assign_move.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/assign_move.pass.cpp index 8791380..2200367 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/assign_move.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/assign_move.pass.cpp @@ -14,6 +14,7 @@ // vector& operator=(vector&& c); #include <cassert> +#include <utility> #include <vector> #include "min_allocator.h" diff --git a/libcxx/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp index 0801709..a95d358 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp @@ -16,8 +16,9 @@ // For vector<>, this was added to the standard by N4258, // but vector<bool> was not changed. -#include <vector> #include <cassert> +#include <vector> +#include <type_traits> #include "test_macros.h" #include "test_allocator.h" diff --git a/libcxx/test/std/containers/sequences/vector.bool/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/dtor_noexcept.pass.cpp index f8f3c76..6a6ca6b 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/dtor_noexcept.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/dtor_noexcept.pass.cpp @@ -12,8 +12,9 @@ // UNSUPPORTED: c++03 -#include <vector> #include <cassert> +#include <vector> +#include <type_traits> #include "test_macros.h" #include "test_allocator.h" diff --git a/libcxx/test/std/containers/sequences/vector.bool/move_assign_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/move_assign_noexcept.pass.cpp index 5a69213..e5add73 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/move_assign_noexcept.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/move_assign_noexcept.pass.cpp @@ -17,8 +17,9 @@ // UNSUPPORTED: c++03 -#include <vector> #include <cassert> +#include <vector> +#include <type_traits> #include "test_macros.h" #include "test_allocator.h" diff --git a/libcxx/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp index d0d231f..5bdae01 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp @@ -15,8 +15,9 @@ // UNSUPPORTED: c++03 -#include <vector> #include <cassert> +#include <vector> +#include <type_traits> #include "test_macros.h" #include "test_allocator.h" diff --git a/libcxx/test/std/containers/sequences/vector/vector.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.cons/dtor_noexcept.pass.cpp index 4a7e2cf..331b360 100644 --- a/libcxx/test/std/containers/sequences/vector/vector.cons/dtor_noexcept.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector/vector.cons/dtor_noexcept.pass.cpp @@ -12,8 +12,9 @@ // UNSUPPORTED: c++03 -#include <vector> #include <cassert> +#include <vector> +#include <type_traits> #include "test_macros.h" #include "MoveOnly.h" diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp index 5797599..cf148fd 100644 --- a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp @@ -12,8 +12,9 @@ // UNSUPPORTED: c++03 -#include <unordered_map> #include <cassert> +#include <unordered_map> +#include <type_traits> #include "test_macros.h" #include "MoveOnly.h" diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/erase_range.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/erase_range.pass.cpp index 5324134..8137163 100644 --- a/libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/erase_range.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/erase_range.pass.cpp @@ -57,6 +57,28 @@ int main(int, char**) { assert(c.size() == 0); assert(k == c.end()); } + { // Make sure that we're properly updating the bucket list when we're erasing to the end + std::unordered_map<int, int> m; + m.insert(std::make_pair(1, 1)); + m.insert(std::make_pair(2, 2)); + + { + auto pair = m.equal_range(1); + assert(pair.first != pair.second); + m.erase(pair.first, pair.second); + } + + { + auto pair = m.equal_range(2); + assert(pair.first != pair.second); + m.erase(pair.first, pair.second); + } + + m.insert(std::make_pair(3, 3)); + assert(m.size() == 1); + assert(*m.begin() == std::make_pair(3, 3)); + assert(++m.begin() == m.end()); + } #if TEST_STD_VER >= 11 { typedef std::unordered_map<int, diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp index 6fdc9e3..2771e64 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp @@ -12,8 +12,9 @@ // UNSUPPORTED: c++03 -#include <unordered_map> #include <cassert> +#include <unordered_map> +#include <type_traits> #include "test_macros.h" #include "MoveOnly.h" diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_range.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_range.pass.cpp index 38b75c0..aa6bc20 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_range.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_range.pass.cpp @@ -122,6 +122,28 @@ int main(int, char**) { for (const auto& v : map) assert(v.first == 1 || v.first == collision_val); } + { // Make sure that we're properly updating the bucket list when we're erasing to the end + std::unordered_multimap<int, int> m; + m.insert(std::make_pair(1, 1)); + m.insert(std::make_pair(2, 2)); + + { + auto pair = m.equal_range(1); + assert(pair.first != pair.second); + m.erase(pair.first, pair.second); + } + + { + auto pair = m.equal_range(2); + assert(pair.first != pair.second); + m.erase(pair.first, pair.second); + } + + m.insert(std::make_pair(3, 3)); + assert(m.size() == 1); + assert(*m.begin() == std::make_pair(3, 3)); + assert(++m.begin() == m.end()); + } #if TEST_STD_VER >= 11 { typedef std::unordered_multimap<int, diff --git a/libcxx/test/std/containers/unord/unord.multiset/erase_range.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/erase_range.pass.cpp index 3bc686e..013e052 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/erase_range.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/erase_range.pass.cpp @@ -64,6 +64,28 @@ int main(int, char**) { for (const auto& v : map) assert(v == 1 || v == collision_val); } + { // Make sure that we're properly updating the bucket list when we're erasing to the end + std::unordered_multiset<int> m; + m.insert(1); + m.insert(2); + + { + auto pair = m.equal_range(1); + assert(pair.first != pair.second); + m.erase(pair.first, pair.second); + } + + { + auto pair = m.equal_range(2); + assert(pair.first != pair.second); + m.erase(pair.first, pair.second); + } + + m.insert(3); + assert(m.size() == 1); + assert(*m.begin() == 3); + assert(++m.begin() == m.end()); + } #if TEST_STD_VER >= 11 { typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/dtor_noexcept.pass.cpp index 32c757e1..c48c286 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/dtor_noexcept.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/dtor_noexcept.pass.cpp @@ -12,8 +12,9 @@ // UNSUPPORTED: c++03 -#include <unordered_set> #include <cassert> +#include <unordered_set> +#include <type_traits> #include "test_macros.h" #include "MoveOnly.h" diff --git a/libcxx/test/std/containers/unord/unord.set/erase_range.pass.cpp b/libcxx/test/std/containers/unord/unord.set/erase_range.pass.cpp index 5fa6e41..1f049a2 100644 --- a/libcxx/test/std/containers/unord/unord.set/erase_range.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/erase_range.pass.cpp @@ -47,6 +47,28 @@ int main(int, char**) { assert(c.size() == 0); assert(k == c.end()); } + { // Make sure that we're properly updating the bucket list when we're erasing to the end + std::unordered_set<int> m; + m.insert(1); + m.insert(2); + + { + auto pair = m.equal_range(1); + assert(pair.first != pair.second); + m.erase(pair.first, pair.second); + } + + { + auto pair = m.equal_range(2); + assert(pair.first != pair.second); + m.erase(pair.first, pair.second); + } + + m.insert(3); + assert(m.size() == 1); + assert(*m.begin() == 3); + assert(++m.begin() == m.end()); + } #if TEST_STD_VER >= 11 { typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C; diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/dtor_noexcept.pass.cpp index 17cfae0..2939e36 100644 --- a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/dtor_noexcept.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/dtor_noexcept.pass.cpp @@ -12,8 +12,9 @@ // UNSUPPORTED: c++03 -#include <unordered_set> #include <cassert> +#include <unordered_set> +#include <type_traits> #include "test_macros.h" #include "MoveOnly.h" diff --git a/libcxx/test/std/depr/depr.cpp.headers/ccomplex.verify.cpp b/libcxx/test/std/depr/depr.cpp.headers/ccomplex.verify.cpp index 0eaf82ce..900ca0e 100644 --- a/libcxx/test/std/depr/depr.cpp.headers/ccomplex.verify.cpp +++ b/libcxx/test/std/depr/depr.cpp.headers/ccomplex.verify.cpp @@ -14,12 +14,11 @@ // UNSUPPORTED: c++03, c++11, c++14 // UNSUPPORTED: clang-modules-build -#include "test_macros.h" +// FIXME: using `#warning` causes diagnostics from system headers which include deprecated headers. This can only be +// enabled again once https://github.com/llvm/llvm-project/pull/168041 (or a similar feature) has landed, since that +// allows suppression in system headers. +// XFAIL: * #include <ccomplex> -#if TEST_STD_VER >= 20 -// expected-warning@ccomplex:* {{'__standard_header_ccomplex' is deprecated: removed in C++20. Include <complex> instead.}} -#else -// expected-warning@ccomplex:* {{'__standard_header_ccomplex' is deprecated: Include <complex> instead.}} -#endif +// expected-warning@ccomplex:* {{<ccomplex> is deprecated in C++17 and removed in C++20. Include <complex> instead.}} diff --git a/libcxx/test/std/depr/depr.cpp.headers/ciso646.verify.cpp b/libcxx/test/std/depr/depr.cpp.headers/ciso646.verify.cpp index 04acd10..a1ca842 100644 --- a/libcxx/test/std/depr/depr.cpp.headers/ciso646.verify.cpp +++ b/libcxx/test/std/depr/depr.cpp.headers/ciso646.verify.cpp @@ -14,5 +14,11 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17 // UNSUPPORTED: clang-modules-build +// FIXME: using `#warning` causes diagnostics from system headers which include deprecated headers. This can only be +// enabled again once https://github.com/llvm/llvm-project/pull/168041 (or a similar feature) has landed, since that +// allows suppression in system headers. +// XFAIL: * + #include <ciso646> -// expected-warning@ciso646:* {{'__standard_header_ciso646' is deprecated: removed in C++20. Include <version> instead.}} + +// expected-warning@ciso646:* {{<ciso646> is removed in C++20. Include <version> instead.}} diff --git a/libcxx/test/std/depr/depr.cpp.headers/cstdalign.verify.cpp b/libcxx/test/std/depr/depr.cpp.headers/cstdalign.verify.cpp index dc9f1af..503a876 100644 --- a/libcxx/test/std/depr/depr.cpp.headers/cstdalign.verify.cpp +++ b/libcxx/test/std/depr/depr.cpp.headers/cstdalign.verify.cpp @@ -14,12 +14,11 @@ // UNSUPPORTED: c++03, c++11, c++14 // UNSUPPORTED: clang-modules-build -#include "test_macros.h" +// FIXME: using `#warning` causes diagnostics from system headers which include deprecated headers. This can only be +// enabled again once https://github.com/llvm/llvm-project/pull/168041 (or a similar feature) has landed, since that +// allows suppression in system headers. +// XFAIL: * #include <cstdalign> -#if TEST_STD_VER >= 20 -// expected-warning@cstdalign:* {{'__standard_header_cstdalign' is deprecated: removed in C++20.}} -#else -// expected-warning@cstdalign:* {{'__standard_header_cstdalign' is deprecated}} -#endif +// expected-warning@cstdalign:* {{<cstdalign> is deprecated in C++17 and removed in C++20.}} diff --git a/libcxx/test/std/depr/depr.cpp.headers/cstdbool.verify.cpp b/libcxx/test/std/depr/depr.cpp.headers/cstdbool.verify.cpp index eddefe1..80025c5 100644 --- a/libcxx/test/std/depr/depr.cpp.headers/cstdbool.verify.cpp +++ b/libcxx/test/std/depr/depr.cpp.headers/cstdbool.verify.cpp @@ -14,12 +14,11 @@ // UNSUPPORTED: c++03, c++11, c++14 // UNSUPPORTED: clang-modules-build -#include "test_macros.h" +// FIXME: using `#warning` causes diagnostics from system headers which include deprecated headers. This can only be +// enabled again once https://github.com/llvm/llvm-project/pull/168041 (or a similar feature) has landed, since that +// allows suppression in system headers. +// XFAIL: * #include <cstdbool> -#if TEST_STD_VER >= 20 -// expected-warning@cstdbool:* {{'__standard_header_cstdbool' is deprecated: removed in C++20.}} -#else -// expected-warning@cstdbool:* {{'__standard_header_cstdbool' is deprecated}} -#endif +// expected-warning@cstdbool:* {{<cstdbool> is deprecated in C++17 and removed in C++20.}} diff --git a/libcxx/test/std/depr/depr.cpp.headers/ctgmath.verify.cpp b/libcxx/test/std/depr/depr.cpp.headers/ctgmath.verify.cpp index 097ab16..07bdd29 100644 --- a/libcxx/test/std/depr/depr.cpp.headers/ctgmath.verify.cpp +++ b/libcxx/test/std/depr/depr.cpp.headers/ctgmath.verify.cpp @@ -14,12 +14,11 @@ // UNSUPPORTED: c++03, c++11, c++14 // UNSUPPORTED: clang-modules-build -#include "test_macros.h" +// FIXME: using `#warning` causes diagnostics from system headers which include deprecated headers. This can only be +// enabled again once https://github.com/llvm/llvm-project/pull/168041 (or a similar feature) has landed, since that +// allows suppression in system headers. +// XFAIL: * #include <ctgmath> -#if TEST_STD_VER >= 20 -// expected-warning@ctgmath:* {{'__standard_header_ctgmath' is deprecated: removed in C++20. Include <cmath> and <complex> instead.}} -#else -// expected-warning@ctgmath:* {{'__standard_header_ctgmath' is deprecated: Include <cmath> and <complex> instead.}} -#endif +// expected-warning@ctgmath:* {{<ctgmath> is deprecated in C++17 and removed in C++20. Include <cmath> and <complex> instead.}} diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp index 5425203..513af522 100644 --- a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp +++ b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp @@ -48,7 +48,7 @@ int main(int, char**) // responds with an empty message, which we probably want to // treat as a failure code otherwise, but we can detect that // with the preprocessor. -#if defined(_NEWLIB_VERSION) +#if _LIBCPP_LIBC_NEWLIB const bool is_newlib = true; #else const bool is_newlib = false; diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp index 255cbe7..1803c0a1 100644 --- a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp +++ b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp @@ -59,7 +59,7 @@ int main(int, char**) { // responds with an empty message, which we probably want to // treat as a failure code otherwise, but we can detect that // with the preprocessor. -#if defined(_NEWLIB_VERSION) +#if _LIBCPP_LIBC_NEWLIB const bool is_newlib = true; #else const bool is_newlib = false; diff --git a/libcxx/test/std/input.output/file.streams/c.files/gets.compile.fail.cpp b/libcxx/test/std/input.output/file.streams/c.files/gets-removed.verify.cpp index 1a92cc9..fb49375 100644 --- a/libcxx/test/std/input.output/file.streams/c.files/gets.compile.fail.cpp +++ b/libcxx/test/std/input.output/file.streams/c.files/gets-removed.verify.cpp @@ -7,15 +7,11 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11 -// test <cstdio> -// gets +// Verify that std::gets has been removed in C++14 and later #include <cstdio> -int main(int, char**) -{ - (void) std::gets((char *) NULL); - - return 0; +void f(char* str) { + (void)std::gets(str); // expected-error {{no member named 'gets' in namespace 'std'}} } diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.pass.cpp new file mode 100644 index 0000000..de17cd4 --- /dev/null +++ b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// FILE_DEPENDENCIES: xsgetn.test.dat + +// <fstream> + +// template <class charT, class traits = char_traits<charT> > +// class basic_ifstream + +// streamsize xsgetn(char_type*, streamsize) override; + +// This isn't a required override by the standard, but most implementations +// override it, since it allows for significantly improved performance in some +// cases. All of this code is required to work, so this isn't a libc++ extension + +#include <cassert> +#include <fstream> +#include <vector> + +#include "test_macros.h" + +int main(int, char**) { + std::vector<char> stream_buffer(10); + std::ifstream fs("xsgetn.test.dat"); + std::filebuf* fb = fs.rdbuf(); + fb->pubsetbuf(stream_buffer.data(), 10); + + // Ensure that the buffer is set up + assert(fb->sgetc() == 't'); + + std::vector<char> test_buffer(5); + test_buffer[0] = '\0'; + + { // Check that a read smaller than the buffer works fine + assert(fb->sgetn(test_buffer.data(), 5) == 5); + assert(std::string(test_buffer.data(), 5) == "this "); + } + { // Check that reading up to the buffer end works fine + assert(fb->sgetn(test_buffer.data(), 5) == 5); + assert(std::string(test_buffer.data(), 5) == "is so"); + } + { // Check that reading from an empty buffer, but more than the buffer can + // hold works fine + test_buffer.resize(12); + assert(fb->sgetn(test_buffer.data(), 12) == 12); + assert(std::string(test_buffer.data(), 12) == "me random da"); + } + { // Check that reading from a non-empty buffer, and more than the buffer can + // hold works fine Fill the buffer up + test_buffer.resize(2); + assert(fb->sgetn(test_buffer.data(), 2) == 2); + assert(std::string(test_buffer.data(), 2) == "ta"); + + // Do the actual check + test_buffer.resize(12); + assert(fb->sgetn(test_buffer.data(), 12) == 12); + assert(std::string(test_buffer.data(), 12) == " to be able "); + } + { // Check that trying to read more than the file size works fine + test_buffer.resize(30); + assert(fb->sgetn(test_buffer.data(), 30) == 24); + test_buffer.resize(24); + assert(std::string(test_buffer.data(), 24) == "to test buffer behaviour"); + } + + return 0; +} diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.test.dat b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.test.dat new file mode 100644 index 0000000..06d663b --- /dev/null +++ b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.test.dat @@ -0,0 +1 @@ +this is some random data to be able to test buffer behaviour
\ No newline at end of file diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp index b3d87ee..65c4dab 100644 --- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp @@ -32,6 +32,7 @@ #include <type_traits> #include <string_view> #include <cassert> +#include <utility> // On Windows, the append function converts all inputs (pointers, iterators) // to an intermediate path object, causing allocations in cases where no diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp index 96de72b..d4a3273 100644 --- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp @@ -39,6 +39,7 @@ #include <string> #include <string_view> #include <cassert> +#include <utility> // On Windows, charset conversions cause allocations in the path class in // cases where no allocations are done on other platforms. diff --git a/libcxx/test/std/language.support/support.dynamic/hardware_inference_size.compile.pass.cpp b/libcxx/test/std/language.support/support.dynamic/hardware_inference_size.compile.pass.cpp index 2656f05..aed3d42 100644 --- a/libcxx/test/std/language.support/support.dynamic/hardware_inference_size.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/hardware_inference_size.compile.pass.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14 -// UNSUPPORTED: (clang || apple-clang) && stdlib=libc++ #include <new> diff --git a/libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp b/libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp index 66e149b..c08f9db 100644 --- a/libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp @@ -10,6 +10,8 @@ // traps +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + #include <limits> #include "test_macros.h" @@ -33,17 +35,17 @@ test() int main(int, char**) { test<bool, false>(); - test<char, integral_types_trap>(); - test<signed char, integral_types_trap>(); - test<unsigned char, integral_types_trap>(); - test<wchar_t, integral_types_trap>(); + test<char, false>(); + test<signed char, false>(); + test<unsigned char, false>(); + test<wchar_t, false>(); #if TEST_STD_VER > 17 && defined(__cpp_char8_t) - test<char8_t, integral_types_trap>(); + test<char8_t, false>(); #endif - test<char16_t, integral_types_trap>(); - test<char32_t, integral_types_trap>(); - test<short, integral_types_trap>(); - test<unsigned short, integral_types_trap>(); + test<char16_t, false>(); + test<char32_t, false>(); + test<short, false>(); + test<unsigned short, false>(); test<int, integral_types_trap>(); test<unsigned int, integral_types_trap>(); test<long, integral_types_trap>(); diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp index aca6290..c4e6529 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp @@ -142,8 +142,8 @@ # ifndef __cpp_lib_optional # error "__cpp_lib_optional should be defined in c++26" # endif -# if __cpp_lib_optional != 202110L -# error "__cpp_lib_optional should have the value 202110L in c++26" +# if __cpp_lib_optional != 202506L +# error "__cpp_lib_optional should have the value 202506L in c++26" # endif # ifndef __cpp_lib_optional_range_support diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp index 8189c5c..996ec29 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp @@ -7509,8 +7509,8 @@ # ifndef __cpp_lib_optional # error "__cpp_lib_optional should be defined in c++26" # endif -# if __cpp_lib_optional != 202110L -# error "__cpp_lib_optional should have the value 202110L in c++26" +# if __cpp_lib_optional != 202506L +# error "__cpp_lib_optional should have the value 202506L in c++26" # endif # ifndef __cpp_lib_optional_range_support diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp index 0154082..45b0348 100644 --- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp +++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp @@ -13,6 +13,8 @@ // iter_type get(iter_type in, iter_type end, ios_base&, // ios_base::iostate& err, long& v) const; +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + #include <locale> #include <ios> #include <cassert> @@ -99,6 +101,18 @@ int main(int, char**) assert(v == 291); } { + const char str[] = "a123"; + std::dec(ios); + std::ios_base::iostate err = ios.goodbit; + cpp17_input_iterator<const char*> iter = + f.get(cpp17_input_iterator<const char*>(str), + cpp17_input_iterator<const char*>(str+sizeof(str)), + ios, err, v); + assert(base(iter) == str); + assert(err == ios.failbit); + assert(v == 0); + } + { const char str[] = "0x123"; std::hex(ios); std::ios_base::iostate err = ios.goodbit; @@ -519,6 +533,238 @@ int main(int, char**) assert(err == ios.failbit); assert(v == std::numeric_limits<long>::max()); } + { + v = -1; + const char str[] = ""; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator<const char*> iter = + f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str), ios, err, v); + assert(base(iter) == str); + assert(err == (std::ios::eofbit | std::ios::failbit)); + assert(v == 0); + } + { + v = -1; + const char str[] = "+"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator<const char*> iter = + f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 1), ios, err, v); + assert(base(iter) == str + 1); + assert(err == (std::ios::eofbit | std::ios::failbit)); + assert(v == 0); + } + { + v = -1; + const char str[] = "+"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator<const char*> iter = f.get( + cpp17_input_iterator<const char*>(std::begin(str)), + cpp17_input_iterator<const char*>(std::end(str)), + ios, + err, + v); + assert(base(iter) == str + 1); + assert(err == ios.failbit); + assert(v == 0); + } + { + v = -1; + const char str[] = "-"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator<const char*> iter = f.get( + cpp17_input_iterator<const char*>(std::begin(str)), + cpp17_input_iterator<const char*>(std::end(str)), + ios, + err, + v); + assert(base(iter) == str + 1); + assert(err == ios.failbit); + assert(v == 0); + } + { + v = -1; + const char str[] = "0"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator<const char*> iter = f.get( + cpp17_input_iterator<const char*>(std::begin(str)), + cpp17_input_iterator<const char*>(std::end(str)), + ios, + err, + v); + assert(base(iter) == str + 1); + assert(err == ios.goodbit); + assert(v == 0); + } + { + v = -1; + const char str[] = "078"; + std::ios_base::iostate err = ios.goodbit; + + ios.flags(ios.flags() & ~ios.basefield); + cpp17_input_iterator<const char*> iter = f.get( + cpp17_input_iterator<const char*>(std::begin(str)), + cpp17_input_iterator<const char*>(std::end(str)), + ios, + err, + v); + assert(base(iter) == str + 2); + assert(err == ios.goodbit); + assert(v == 7); + ios.flags(ios.flags() | ios.dec); + } + { + v = -1; + std::string str = std::to_string(std::numeric_limits<unsigned long>::max()) + "99a"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator<const char*> iter = f.get( + cpp17_input_iterator<const char*>(str.data()), + cpp17_input_iterator<const char*>(str.data() + str.size()), + ios, + err, + v); + assert(base(iter) == str.data() + str.size() - 1); + assert(err == ios.failbit); + assert(v == std::numeric_limits<long>::max()); + } + { + std::string str = std::to_string(std::numeric_limits<long>::max()) + 'c'; + std::ios_base::iostate err = ios.goodbit; + cpp17_input_iterator<const char*> iter = + f.get(cpp17_input_iterator<const char*>(str.data()), + cpp17_input_iterator<const char*>(str.data() + str.size()), + ios, err, v); + assert(base(iter) == str.data() + str.size() - 1); + assert(err == ios.goodbit); + assert(v == std::numeric_limits<long>::max()); + } + { + std::string str = std::to_string(static_cast<unsigned long>(std::numeric_limits<long>::max()) + 1) + 'c'; + std::ios_base::iostate err = ios.goodbit; + cpp17_input_iterator<const char*> iter = f.get( + cpp17_input_iterator<const char*>(str.data()), + cpp17_input_iterator<const char*>(str.data() + str.size()), + ios, + err, + v); + assert(base(iter) == str.data() + str.size() - 1); + assert(err == ios.failbit); + assert(v == std::numeric_limits<long>::max()); + } + { + std::string str = '-' + std::to_string(static_cast<unsigned long>(std::numeric_limits<long>::max()) + 2) + 'c'; + std::ios_base::iostate err = ios.goodbit; + cpp17_input_iterator<const char*> iter = f.get( + cpp17_input_iterator<const char*>(str.data()), + cpp17_input_iterator<const char*>(str.data() + str.size()), + ios, + err, + v); + assert(base(iter) == str.data() + str.size() - 1); + assert(err == ios.failbit); + assert(v == std::numeric_limits<long>::min()); + } + + { // Check that auto-detection of the base works properly + ios.flags(ios.flags() & ~std::ios::basefield); + { // zeroes + { + v = -1; + const char str[] = "0"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator<const char*> iter = + f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 1), ios, err, v); + assert(base(iter) == str + 1); + assert(err == ios.eofbit); + assert(v == 0); + } + { + v = -1; + const char str[] = "00"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator<const char*> iter = + f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 2), ios, err, v); + assert(base(iter) == str + 2); + assert(err == ios.eofbit); + assert(v == 0); + } + { + v = -1; + const char str[] = "0x0"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator<const char*> iter = + f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 3), ios, err, v); + assert(base(iter) == str + 3); + assert(err == ios.eofbit); + assert(v == 0); + } + { + v = -1; + const char str[] = "0X0"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator<const char*> iter = + f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 3), ios, err, v); + assert(base(iter) == str + 3); + assert(err == ios.eofbit); + assert(v == 0); + } + } + { // first character after base is out of range + { + v = -1; + const char str[] = "08"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator<const char*> iter = + f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 2), ios, err, v); + assert(base(iter) == str + 1); + assert(err == ios.goodbit); + assert(v == 0); + } + { + v = -1; + const char str[] = "1a"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator<const char*> iter = + f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 2), ios, err, v); + assert(base(iter) == str + 1); + assert(err == ios.goodbit); + assert(v == 1); + } + { + v = -1; + const char str[] = "0xg"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator<const char*> iter = + f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 3), ios, err, v); + assert(base(iter) == str + 2); + assert(err == ios.failbit); + assert(v == 0); + } + { + v = -1; + const char str[] = "0Xg"; + std::ios_base::iostate err = ios.goodbit; + + cpp17_input_iterator<const char*> iter = + f.get(cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + 3), ios, err, v); + assert(base(iter) == str + 2); + assert(err == ios.failbit); + assert(v == 0); + } + } + } return 0; } diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_int.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_int.pass.cpp index bee1be0..f9cef08 100644 --- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_int.pass.cpp +++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_int.pass.cpp @@ -68,6 +68,17 @@ int main(int, char**) assert(err == ios.goodbit); assert(v == 1); } + { + const char str[] = "-1"; + std::ios_base::iostate err = ios.goodbit; + cpp17_input_iterator<const char*> iter = + f.get(cpp17_input_iterator<const char*>(str), + cpp17_input_iterator<const char*>(str+sizeof(str)), + ios, err, v); + assert(base(iter) == str+sizeof(str)-1); + assert(err == ios.goodbit); + assert(v == std::numeric_limits<unsigned int>::max()); + } std::hex(ios); { const char str[] = "0xFFFFFFFF"; diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long.pass.cpp index b087bdc..fed6fc0 100644 --- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long.pass.cpp +++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long.pass.cpp @@ -68,6 +68,17 @@ int main(int, char**) assert(err == ios.goodbit); assert(v == 1); } + { + const char str[] = "-1"; + std::ios_base::iostate err = ios.goodbit; + cpp17_input_iterator<const char*> iter = + f.get(cpp17_input_iterator<const char*>(str), + cpp17_input_iterator<const char*>(str+sizeof(str)), + ios, err, v); + assert(base(iter) == str+sizeof(str)-1); + assert(err == ios.goodbit); + assert(v == std::numeric_limits<unsigned long>::max()); + } std::hex(ios); { const char str[] = "0xFFFFFFFF"; diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long_long.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long_long.pass.cpp index 6769aeb..0bdb6c1 100644 --- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long_long.pass.cpp +++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_long_long.pass.cpp @@ -68,6 +68,17 @@ int main(int, char**) assert(err == ios.goodbit); assert(v == 1); } + { + const char str[] = "-1"; + std::ios_base::iostate err = ios.goodbit; + cpp17_input_iterator<const char*> iter = + f.get(cpp17_input_iterator<const char*>(str), + cpp17_input_iterator<const char*>(str+sizeof(str)), + ios, err, v); + assert(base(iter) == str+sizeof(str)-1); + assert(err == ios.goodbit); + assert(v == std::numeric_limits<unsigned long long>::max()); + } std::hex(ios); { const char str[] = "0xFFFFFFFFFFFFFFFF"; diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_short.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_short.pass.cpp index bec9a7f..decfbe9 100644 --- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_short.pass.cpp +++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_unsigned_short.pass.cpp @@ -68,6 +68,17 @@ int main(int, char**) assert(err == ios.goodbit); assert(v == 1); } + { + const char str[] = "-1"; + std::ios_base::iostate err = ios.goodbit; + cpp17_input_iterator<const char*> iter = + f.get(cpp17_input_iterator<const char*>(str), + cpp17_input_iterator<const char*>(str+sizeof(str)), + ios, err, v); + assert(base(iter) == str+sizeof(str)-1); + assert(err == ios.goodbit); + assert(v == std::numeric_limits<unsigned short>::max()); + } std::hex(ios); { const char str[] = "0xFFFF"; diff --git a/libcxx/test/std/numerics/c.math/isnormal.pass.cpp b/libcxx/test/std/numerics/c.math/isnormal.pass.cpp index 76c3d13..79465b3 100644 --- a/libcxx/test/std/numerics/c.math/isnormal.pass.cpp +++ b/libcxx/test/std/numerics/c.math/isnormal.pass.cpp @@ -14,6 +14,7 @@ #include <cassert> #include <cmath> #include <limits> +#include <type_traits> #include "test_macros.h" #include "type_algorithms.h" diff --git a/libcxx/test/std/numerics/c.math/signbit.pass.cpp b/libcxx/test/std/numerics/c.math/signbit.pass.cpp index 233e8ed..5655370 100644 --- a/libcxx/test/std/numerics/c.math/signbit.pass.cpp +++ b/libcxx/test/std/numerics/c.math/signbit.pass.cpp @@ -20,6 +20,7 @@ #include <cassert> #include <cmath> #include <limits> +#include <type_traits> #include "test_macros.h" #include "type_algorithms.h" diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/increment.pass.cpp index 4d765d7..b557346 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/increment.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/increment.pass.cpp @@ -75,6 +75,56 @@ constexpr bool test() { } } + // LWG3505 + { + using namespace std::string_view_literals; + + { // Motivational example + auto v = std::views::lazy_split("xxyx"sv, "xy"sv); + + { + auto i = v.begin(); + assert(std::ranges::equal(*i, "x"s)); + + decltype(auto) i2 = ++i; + static_assert(std::is_lvalue_reference_v<decltype(i2)>); + assert(std::ranges::equal(*i2, "x"s)); + } + + { + auto i = v.begin(); + assert(std::ranges::equal(*i, "x"s)); + + decltype(auto) i2 = i++; + static_assert(!std::is_reference_v<decltype(i2)>); + assert(std::ranges::equal(*i2, "x"s)); + assert(std::ranges::equal(*i, "x"s)); + } + } + { + auto v = std::views::lazy_split("zzht"sv, "zh"sv); + + { + auto i = v.begin(); + assert(std::ranges::equal(*i, "z"s)); + + decltype(auto) i2 = ++i; + static_assert(std::is_lvalue_reference_v<decltype(i2)>); + assert(std::ranges::equal(*i2, "t"s)); + } + + { + auto i = v.begin(); + assert(std::ranges::equal(*i, "z"s)); + + decltype(auto) i2 = i++; + static_assert(!std::is_reference_v<decltype(i2)>); + assert(std::ranges::equal(*i2, "z"s)); + assert(std::ranges::equal(*i, "t"s)); + } + } + } + return true; } diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp index d92b6cb..8723085 100644 --- a/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp @@ -12,13 +12,15 @@ // inline constexpr unspecified indices = unspecified; +// FIXME: This test shouldn't define TEST_HAS_NO_INT128 +// ADDITIONAL_COMPILE_FLAGS(clang-modules-build): -fno-modules + #include <cassert> #include <cstddef> #include <ranges> #include <vector> #include "test_macros.h" -#define TEST_HAS_NO_INT128 // Size cannot be larger than 64 bits #include "type_algorithms.h" #include "types.h" diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/member_typedefs.compile.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/member_typedefs.compile.pass.cpp index c2f7fd1..0d6fc9c 100644 --- a/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/member_typedefs.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/member_typedefs.compile.pass.cpp @@ -106,7 +106,12 @@ void test() { // Same as below, if there is no type larger than long, we can just use that. static_assert(sizeof(Iter::difference_type) >= sizeof(long)); static_assert(std::is_signed_v<Iter::difference_type>); +#ifdef TEST_HAS_NO_INT128 LIBCPP_STATIC_ASSERT(std::same_as<Iter::difference_type, long long>); +#else + LIBCPP_STATIC_ASSERT(std::same_as<Iter::difference_type, + std::conditional_t<sizeof(long) == sizeof(long long), __int128, long long>>); +#endif } { const std::ranges::iota_view<long long> io(0); @@ -118,7 +123,11 @@ void test() { // https://eel.is/c++draft/range.iota.view#1.3 static_assert(sizeof(Iter::difference_type) >= sizeof(long long)); static_assert(std::is_signed_v<Iter::difference_type>); +#ifdef TEST_HAS_NO_INT128 LIBCPP_STATIC_ASSERT(std::same_as<Iter::difference_type, long long>); +#else + LIBCPP_STATIC_ASSERT(std::same_as<Iter::difference_type, __int128>); +#endif } { const std::ranges::iota_view<Decrementable> io; diff --git a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/array.compile.fail.cpp b/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/array.compile.fail.cpp deleted file mode 100644 index a03fd52..0000000 --- a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/array.compile.fail.cpp +++ /dev/null @@ -1,40 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// <regex> - -// class regex_iterator<BidirectionalIterator, charT, traits> - -// template <size_t N> -// regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, -// const regex_type&& re, -// const int (&submatches)[N], -// regex_constants::match_flag_type m = -// regex_constants::match_default); - -#include <regex> -#include <vector> -#include <cassert> -#include "test_macros.h" - -#if TEST_STD_VER < 14 -#error -#endif - -int main(int, char**) -{ - { - std::regex phone_numbers("\\d{3}-(\\d{4})"); - const char phone_book[] = "start 555-1234, 555-2345, 555-3456 end"; - const int indices[] = {-1, 0, 1}; - std::cregex_token_iterator i(std::begin(phone_book), std::end(phone_book)-1, - std::regex("\\d{3}-\\d{4}"), indices); - } - - return 0; -} diff --git a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/init.compile.fail.cpp b/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/init.compile.fail.cpp deleted file mode 100644 index b6913e6..0000000 --- a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/init.compile.fail.cpp +++ /dev/null @@ -1,37 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// <regex> - -// class regex_iterator<BidirectionalIterator, charT, traits> - -// regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, -// const regex_type&& re, -// initializer_list<int> submatches, -// regex_constants::match_flag_type m = -// regex_constants::match_default); - -#include <regex> -#include <cassert> -#include "test_macros.h" - -#if TEST_STD_VER < 14 -#error -#endif - -int main(int, char**) -{ - { - std::regex phone_numbers("\\d{3}-(\\d{4})"); - const char phone_book[] = "start 555-1234, 555-2345, 555-3456 end"; - std::cregex_token_iterator i(std::begin(phone_book), std::end(phone_book)-1, - std::regex("\\d{3}-\\d{4}"), {-1, 0, 1}); - } - - return 0; -} diff --git a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/int.compile.fail.cpp b/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/int.compile.fail.cpp deleted file mode 100644 index 3c39d49..0000000 --- a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/int.compile.fail.cpp +++ /dev/null @@ -1,36 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// <regex> - -// class regex_iterator<BidirectionalIterator, charT, traits> - -// regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, -// const regex_type&& re, int submatch = 0, -// regex_constants::match_flag_type m = -// regex_constants::match_default); - -#include <regex> -#include <cassert> -#include "test_macros.h" - -#if TEST_STD_VER < 14 -#error -#endif - -int main(int, char**) -{ - { - std::regex phone_numbers("\\d{3}-\\d{4}"); - const char phone_book[] = "start 555-1234, 555-2345, 555-3456 end"; - std::cregex_token_iterator i(std::begin(phone_book), std::end(phone_book)-1, - std::regex("\\d{3}-\\d{4}"), -1); - } - - return 0; -} diff --git a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/temporary-objects.verify.cpp b/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/temporary-objects.verify.cpp new file mode 100644 index 0000000..b1ab0f3 --- /dev/null +++ b/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/temporary-objects.verify.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11 + +// Ensure that we don't allow iterators into temporary std::regex objects. + +// <regex> +// +// class regex_iterator<BidirectionalIterator, charT, traits> +// +// regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, +// const regex_type&& re, int submatch = 0, +// regex_constants::match_flag_type m = +// regex_constants::match_default); +// +// template <size_t N> +// regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, +// const regex_type&& re, +// const int (&submatches)[N], +// regex_constants::match_flag_type m = +// regex_constants::match_default); +// +// regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, +// const regex_type&& re, +// initializer_list<int> submatches, +// regex_constants::match_flag_type m = +// regex_constants::match_default); +// +// template <std::size_t N> +// regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, +// const regex_type&& re, +// const std::vector<int>& submatches, +// regex_constants::match_flag_type m = +// regex_constants::match_default); + +#include <iterator> +#include <regex> +#include <vector> + +void f() { + std::regex phone_numbers("\\d{3}-\\d{4}"); + const char phone_book[] = "start 555-1234, 555-2345, 555-3456 end"; + + { // int submatch + std::cregex_token_iterator i(std::begin(phone_book), std::end(phone_book) - 1, std::regex("\\d{3}-\\d{4}"), -1); + // expected-error@-1 {{call to deleted constructor of 'std::cregex_token_iterator'}} + } + { // const int (&submatches)[N] + const int indices[] = {-1, 0, 1}; + std::cregex_token_iterator i( + std::begin(phone_book), std::end(phone_book) - 1, std::regex("\\d{3}-\\d{4}"), indices); + // expected-error@-2 {{call to deleted constructor of 'std::cregex_token_iterator'}} + } + { // initializer_list<int> submatches + std::cregex_token_iterator i( + std::begin(phone_book), std::end(phone_book) - 1, std::regex("\\d{3}-\\d{4}"), {-1, 0, 1}); + // expected-error@-2 {{call to deleted constructor of 'std::cregex_token_iterator'}} + } + { // const std::vector<int>& submatches + std::vector<int> v; + v.push_back(-1); + v.push_back(-1); + std::cregex_token_iterator i(std::begin(phone_book), std::end(phone_book) - 1, std::regex("\\d{3}-\\d{4}"), v); + // expected-error@-1 {{call to deleted constructor of 'std::cregex_token_iterator'}} + } +} diff --git a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/vector.compile.fail.cpp b/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/vector.compile.fail.cpp deleted file mode 100644 index 9b07df9..0000000 --- a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/vector.compile.fail.cpp +++ /dev/null @@ -1,41 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// <regex> - -// class regex_iterator<BidirectionalIterator, charT, traits> - -// template <std::size_t N> -// regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, -// const regex_type&& re, -// const std::vector<int>& submatches, -// regex_constants::match_flag_type m = -// regex_constants::match_default); - -#include <regex> -#include <cassert> -#include "test_macros.h" - -#if TEST_STD_VER < 14 -#error -#endif - -int main(int, char**) -{ - { - std::regex phone_numbers("\\d{3}-(\\d{4})"); - const char phone_book[] = "start 555-1234, 555-2345, 555-3456 end"; - std::vector<int> v; - v.push_back(-1); - v.push_back(-1); - std::cregex_token_iterator i(std::begin(phone_book), std::end(phone_book)-1, - std::regex("\\d{3}-\\d{4}"), v); - } - - return 0; -} diff --git a/libcxx/test/std/re/re.results/re.results.const/move.pass.cpp b/libcxx/test/std/re/re.results/re.results.const/move.pass.cpp index 0806ede..9078d57 100644 --- a/libcxx/test/std/re/re.results/re.results.const/move.pass.cpp +++ b/libcxx/test/std/re/re.results/re.results.const/move.pass.cpp @@ -14,8 +14,10 @@ // // Additionally, the stored Allocator value is move constructed from m.get_allocator(). -#include <regex> #include <cassert> +#include <regex> +#include <utility> + #include "test_macros.h" #include "test_allocator.h" diff --git a/libcxx/test/std/strings/basic.string/string.cons/dtor.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/dtor.pass.cpp index e9f1740..d5c1f4d 100644 --- a/libcxx/test/std/strings/basic.string/string.cons/dtor.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/dtor.pass.cpp @@ -12,11 +12,12 @@ // ~basic_string() // implied noexcept; // constexpr since C++20 -#include <string> #include <cassert> +#include <string> +#include <type_traits> -#include "test_macros.h" #include "test_allocator.h" +#include "test_macros.h" template <class T> struct throwing_alloc { diff --git a/libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp index d9176da..d47c9df 100644 --- a/libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp @@ -25,6 +25,7 @@ #include <iterator> #include <string> #include <type_traits> +#include <utility> #include "test_macros.h" #include "test_allocator.h" diff --git a/libcxx/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp index 3a6f84f..a19564b 100644 --- a/libcxx/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp @@ -19,17 +19,18 @@ // The deduction guide shall not participate in overload resolution if Allocator // is a type that does not qualify as an allocator. -#include <string> -#include <string_view> +#include <cassert> +#include <cstddef> #include <iterator> #include <memory> +#include <string> +#include <string_view> #include <type_traits> -#include <cassert> -#include <cstddef> +#include <utility> -#include "test_macros.h" -#include "test_allocator.h" #include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" template <class StringView, class Allocator, class = void> struct CanDeduce : std::false_type {}; diff --git a/libcxx/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp index 08e696b..e36503d 100644 --- a/libcxx/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp @@ -25,15 +25,16 @@ // The deduction guide shall not participate in overload resolution if Allocator // is a type that does not qualify as an allocator. -#include <string> -#include <string_view> -#include <iterator> #include <cassert> #include <cstddef> +#include <iterator> +#include <string> +#include <string_view> +#include <utility> -#include "test_macros.h" -#include "test_allocator.h" #include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" template <class StringView, class Size, class Allocator, class = void> struct CanDeduce : std::false_type {}; diff --git a/libcxx/test/std/thread/thread.jthread/nodiscard.verify.cpp b/libcxx/test/std/thread/thread.jthread/nodiscard.verify.cpp deleted file mode 100644 index 2ef5cf8..0000000 --- a/libcxx/test/std/thread/thread.jthread/nodiscard.verify.cpp +++ /dev/null @@ -1,29 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// UNSUPPORTED: no-threads -// UNSUPPORTED: c++03, c++11, c++14, c++17 - -// [[nodiscard]] bool joinable() const noexcept; -// [[nodiscard]] id get_id() const noexcept; -// [[nodiscard]] native_handle_type native_handle(); -// [[nodiscard]] stop_source get_stop_source() noexcept; -// [[nodiscard]] stop_token get_stop_token() const noexcept; -// [[nodiscard]] static unsigned int hardware_concurrency() noexcept; - -#include <thread> - -void test() { - std::jthread jt; - jt.joinable(); // expected-warning {{ignoring return value of function}} - jt.get_id(); // expected-warning {{ignoring return value of function}} - jt.native_handle(); // expected-warning {{ignoring return value of function}} - jt.get_stop_source(); // expected-warning {{ignoring return value of function}} - jt.get_stop_token(); // expected-warning {{ignoring return value of function}} - jt.hardware_concurrency(); // expected-warning {{ignoring return value of function}} -} diff --git a/libcxx/test/std/time/time.clock/time.clock.gps/types.compile.pass.cpp b/libcxx/test/std/time/time.clock/time.clock.gps/types.compile.pass.cpp index 006ad9a..fea70a3 100644 --- a/libcxx/test/std/time/time.clock/time.clock.gps/types.compile.pass.cpp +++ b/libcxx/test/std/time/time.clock/time.clock.gps/types.compile.pass.cpp @@ -32,6 +32,7 @@ #include <chrono> #include <concepts> #include <ratio> +#include <type_traits> #include "test_macros.h" diff --git a/libcxx/test/std/time/time.clock/time.clock.tai/types.compile.pass.cpp b/libcxx/test/std/time/time.clock/time.clock.tai/types.compile.pass.cpp index a7123bc..6499ecb 100644 --- a/libcxx/test/std/time/time.clock/time.clock.tai/types.compile.pass.cpp +++ b/libcxx/test/std/time/time.clock/time.clock.tai/types.compile.pass.cpp @@ -32,6 +32,7 @@ #include <chrono> #include <concepts> #include <ratio> +#include <type_traits> #include "test_macros.h" diff --git a/libcxx/test/std/time/time.clock/time.clock.utc/types.compile.pass.cpp b/libcxx/test/std/time/time.clock/time.clock.utc/types.compile.pass.cpp index 8cb3d78..c69671b 100644 --- a/libcxx/test/std/time/time.clock/time.clock.utc/types.compile.pass.cpp +++ b/libcxx/test/std/time/time.clock/time.clock.utc/types.compile.pass.cpp @@ -32,6 +32,7 @@ #include <concepts> #include <chrono> #include <ratio> +#include <type_traits> #include "test_macros.h" diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp index 5143bef..a5f0e8b 100644 --- a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp +++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp @@ -25,156 +25,157 @@ // Test that the operators are properly noexcept. void test_cast_is_noexcept() { - std::any a; - ASSERT_NOEXCEPT(std::any_cast<int>(&a)); + std::any a; + ASSERT_NOEXCEPT(std::any_cast<int>(&a)); - const std::any& ca = a; - ASSERT_NOEXCEPT(std::any_cast<int>(&ca)); + const std::any& ca = a; + ASSERT_NOEXCEPT(std::any_cast<int>(&ca)); } // Test that the return type of any_cast is correct. void test_cast_return_type() { - std::any a; - ASSERT_SAME_TYPE(decltype(std::any_cast<int>(&a)), int*); - ASSERT_SAME_TYPE(decltype(std::any_cast<int const>(&a)), int const*); + std::any a; + ASSERT_SAME_TYPE(decltype(std::any_cast<int>(&a)), int*); + ASSERT_SAME_TYPE(decltype(std::any_cast<int const>(&a)), int const*); - const std::any& ca = a; - ASSERT_SAME_TYPE(decltype(std::any_cast<int>(&ca)), int const*); - ASSERT_SAME_TYPE(decltype(std::any_cast<int const>(&ca)), int const*); + const std::any& ca = a; + ASSERT_SAME_TYPE(decltype(std::any_cast<int>(&ca)), int const*); + ASSERT_SAME_TYPE(decltype(std::any_cast<int const>(&ca)), int const*); } // Test that any_cast handles null pointers. void test_cast_nullptr() { - std::any *a = nullptr; - assert(nullptr == std::any_cast<int>(a)); - assert(nullptr == std::any_cast<int const>(a)); + std::any* a = nullptr; + assert(nullptr == std::any_cast<int>(a)); + assert(nullptr == std::any_cast<int const>(a)); - const std::any *ca = nullptr; - assert(nullptr == std::any_cast<int>(ca)); - assert(nullptr == std::any_cast<int const>(ca)); + const std::any* ca = nullptr; + assert(nullptr == std::any_cast<int>(ca)); + assert(nullptr == std::any_cast<int const>(ca)); } // Test casting an empty object. void test_cast_empty() { - { - std::any a; - assert(nullptr == std::any_cast<int>(&a)); - assert(nullptr == std::any_cast<int const>(&a)); - - const std::any& ca = a; - assert(nullptr == std::any_cast<int>(&ca)); - assert(nullptr == std::any_cast<int const>(&ca)); - } - // Create as non-empty, then make empty and run test. - { - std::any a(42); - a.reset(); - assert(nullptr == std::any_cast<int>(&a)); - assert(nullptr == std::any_cast<int const>(&a)); - - const std::any& ca = a; - assert(nullptr == std::any_cast<int>(&ca)); - assert(nullptr == std::any_cast<int const>(&ca)); - } + { + std::any a; + assert(nullptr == std::any_cast<int>(&a)); + assert(nullptr == std::any_cast<int const>(&a)); + + const std::any& ca = a; + assert(nullptr == std::any_cast<int>(&ca)); + assert(nullptr == std::any_cast<int const>(&ca)); + } + // Create as non-empty, then make empty and run test. + { + std::any a(42); + a.reset(); + assert(nullptr == std::any_cast<int>(&a)); + assert(nullptr == std::any_cast<int const>(&a)); + + const std::any& ca = a; + assert(nullptr == std::any_cast<int>(&ca)); + assert(nullptr == std::any_cast<int const>(&ca)); + } } template <class Type> void test_cast() { - assert(Type::count == 0); - Type::reset(); - { - std::any a = Type(42); - const std::any& ca = a; - assert(Type::count == 1); - assert(Type::copied == 0); - assert(Type::moved == 1); - - // Try a cast to a bad type. - // NOTE: Type cannot be an int. - assert(std::any_cast<int>(&a) == nullptr); - assert(std::any_cast<int const>(&a) == nullptr); - assert(std::any_cast<int const volatile>(&a) == nullptr); - - // Try a cast to the right type, but as a pointer. - assert(std::any_cast<Type*>(&a) == nullptr); - assert(std::any_cast<Type const*>(&a) == nullptr); - - // Check getting a unqualified type from a non-const any. - Type* v = std::any_cast<Type>(&a); - assert(v != nullptr); - assert(v->value == 42); - - // change the stored value and later check for the new value. - v->value = 999; - - // Check getting a const qualified type from a non-const any. - Type const* cv = std::any_cast<Type const>(&a); - assert(cv != nullptr); - assert(cv == v); - assert(cv->value == 999); - - // Check getting a unqualified type from a const any. - cv = std::any_cast<Type>(&ca); - assert(cv != nullptr); - assert(cv == v); - assert(cv->value == 999); - - // Check getting a const-qualified type from a const any. - cv = std::any_cast<Type const>(&ca); - assert(cv != nullptr); - assert(cv == v); - assert(cv->value == 999); - - // Check that no more objects were created, copied or moved. - assert(Type::count == 1); - assert(Type::copied == 0); - assert(Type::moved == 1); - } - assert(Type::count == 0); + assert(Type::count == 0); + Type::reset(); + { + std::any a = Type(42); + const std::any& ca = a; + assert(Type::count == 1); + assert(Type::copied == 0); + assert(Type::moved == 1); + + // Try a cast to a bad type. + // NOTE: Type cannot be an int. + assert(std::any_cast<int>(&a) == nullptr); + assert(std::any_cast<int const>(&a) == nullptr); + assert(std::any_cast<int const volatile>(&a) == nullptr); + + // Try a cast to the right type, but as a pointer. + assert(std::any_cast<Type*>(&a) == nullptr); + assert(std::any_cast<Type const*>(&a) == nullptr); + + // Check getting a unqualified type from a non-const any. + Type* v = std::any_cast<Type>(&a); + assert(v != nullptr); + assert(v->value == 42); + + // change the stored value and later check for the new value. + v->value = 999; + + // Check getting a const qualified type from a non-const any. + Type const* cv = std::any_cast<Type const>(&a); + assert(cv != nullptr); + assert(cv == v); + assert(cv->value == 999); + + // Check getting a unqualified type from a const any. + cv = std::any_cast<Type>(&ca); + assert(cv != nullptr); + assert(cv == v); + assert(cv->value == 999); + + // Check getting a const-qualified type from a const any. + cv = std::any_cast<Type const>(&ca); + assert(cv != nullptr); + assert(cv == v); + assert(cv->value == 999); + + // Check that no more objects were created, copied or moved. + assert(Type::count == 1); + assert(Type::copied == 0); + assert(Type::moved == 1); + } + assert(Type::count == 0); } -void test_cast_non_copyable_type() -{ - // Even though 'any' never stores non-copyable types - // we still need to support any_cast<NoCopy>(ptr) - struct NoCopy { NoCopy(NoCopy const&) = delete; }; - std::any a(42); - std::any const& ca = a; - assert(std::any_cast<NoCopy>(&a) == nullptr); - assert(std::any_cast<NoCopy>(&ca) == nullptr); +void test_cast_non_copyable_type() { + // Even though 'any' never stores non-copyable types + // we still need to support any_cast<NoCopy>(ptr) + struct NoCopy { + NoCopy(NoCopy const&) = delete; + }; + std::any a(42); + std::any const& ca = a; + assert(std::any_cast<NoCopy>(&a) == nullptr); + assert(std::any_cast<NoCopy>(&ca) == nullptr); } void test_cast_array() { - int arr[3]; - std::any a(arr); - RTTI_ASSERT(a.type() == typeid(int*)); // contained value is decayed - // We can't get an array out - int (*p)[3] = std::any_cast<int[3]>(&a); - assert(p == nullptr); + int arr[3]; + std::any a(arr); + RTTI_ASSERT(a.type() == typeid(int*)); // contained value is decayed + // We can't get an array out + int (*p)[3] = std::any_cast<int[3]>(&a); + assert(p == nullptr); } void test_fn() {} void test_cast_function_pointer() { - using T = void(*)(); - std::any a(test_fn); - // An any can never store a function type, but we should at least be able - // to ask. - assert(std::any_cast<void()>(&a) == nullptr); - T fn_ptr = std::any_cast<T>(a); - assert(fn_ptr == test_fn); + using T = void (*)(); + std::any a(test_fn); + // An any can never store a function type, but we should at least be able + // to ask. + assert(std::any_cast<void()>(&a) == nullptr); + T fn_ptr = std::any_cast<T>(a); + assert(fn_ptr == test_fn); } int main(int, char**) { - test_cast_is_noexcept(); - test_cast_return_type(); - test_cast_nullptr(); - test_cast_empty(); - test_cast<small>(); - test_cast<large>(); - test_cast_non_copyable_type(); - test_cast_array(); - test_cast_function_pointer(); + test_cast_is_noexcept(); + test_cast_return_type(); + test_cast_nullptr(); + test_cast_empty(); + test_cast<small>(); + test_cast<large>(); + test_cast_non_copyable_type(); + test_cast_array(); + test_cast_function_pointer(); return 0; } diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp index 079be66..4ba9bf6 100644 --- a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp +++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp @@ -29,278 +29,275 @@ // Test that the operators are NOT marked noexcept. void test_cast_is_not_noexcept() { - std::any a; - static_assert(!noexcept(std::any_cast<int>(static_cast<std::any&>(a))), ""); - static_assert(!noexcept(std::any_cast<int>(static_cast<std::any const&>(a))), ""); - static_assert(!noexcept(std::any_cast<int>(static_cast<std::any &&>(a))), ""); + std::any a; + static_assert(!noexcept(std::any_cast<int>(static_cast<std::any&>(a))), ""); + static_assert(!noexcept(std::any_cast<int>(static_cast<std::any const&>(a))), ""); + static_assert(!noexcept(std::any_cast<int>(static_cast<std::any&&>(a))), ""); } // Test that the return type of any_cast is correct. void test_cast_return_type() { - std::any a; - static_assert(std::is_same<decltype(std::any_cast<int>(a)), int>::value, ""); - static_assert(std::is_same<decltype(std::any_cast<int const>(a)), int>::value, ""); - static_assert(std::is_same<decltype(std::any_cast<int&>(a)), int&>::value, ""); - static_assert(std::is_same<decltype(std::any_cast<int const&>(a)), int const&>::value, ""); - static_assert(std::is_same<decltype(std::any_cast<int&&>(a)), int&&>::value, ""); - static_assert(std::is_same<decltype(std::any_cast<int const&&>(a)), int const&&>::value, ""); - - static_assert(std::is_same<decltype(std::any_cast<int>(std::move(a))), int>::value, ""); - static_assert(std::is_same<decltype(std::any_cast<int const>(std::move(a))), int>::value, ""); - static_assert(std::is_same<decltype(std::any_cast<int&>(std::move(a))), int&>::value, ""); - static_assert(std::is_same<decltype(std::any_cast<int const&>(std::move(a))), int const&>::value, ""); - static_assert(std::is_same<decltype(std::any_cast<int&&>(std::move(a))), int&&>::value, ""); - static_assert(std::is_same<decltype(std::any_cast<int const&&>(std::move(a))), int const&&>::value, ""); - - const std::any& ca = a; - static_assert(std::is_same<decltype(std::any_cast<int>(ca)), int>::value, ""); - static_assert(std::is_same<decltype(std::any_cast<int const>(ca)), int>::value, ""); - static_assert(std::is_same<decltype(std::any_cast<int const&>(ca)), int const&>::value, ""); - static_assert(std::is_same<decltype(std::any_cast<int const&&>(ca)), int const&&>::value, ""); + std::any a; + static_assert(std::is_same<decltype(std::any_cast<int>(a)), int>::value, ""); + static_assert(std::is_same<decltype(std::any_cast<int const>(a)), int>::value, ""); + static_assert(std::is_same<decltype(std::any_cast<int&>(a)), int&>::value, ""); + static_assert(std::is_same<decltype(std::any_cast<int const&>(a)), int const&>::value, ""); + static_assert(std::is_same<decltype(std::any_cast<int&&>(a)), int&&>::value, ""); + static_assert(std::is_same<decltype(std::any_cast<int const&&>(a)), int const&&>::value, ""); + + static_assert(std::is_same<decltype(std::any_cast<int>(std::move(a))), int>::value, ""); + static_assert(std::is_same<decltype(std::any_cast<int const>(std::move(a))), int>::value, ""); + static_assert(std::is_same<decltype(std::any_cast<int&>(std::move(a))), int&>::value, ""); + static_assert(std::is_same<decltype(std::any_cast<int const&>(std::move(a))), int const&>::value, ""); + static_assert(std::is_same<decltype(std::any_cast<int&&>(std::move(a))), int&&>::value, ""); + static_assert(std::is_same<decltype(std::any_cast<int const&&>(std::move(a))), int const&&>::value, ""); + + const std::any& ca = a; + static_assert(std::is_same<decltype(std::any_cast<int>(ca)), int>::value, ""); + static_assert(std::is_same<decltype(std::any_cast<int const>(ca)), int>::value, ""); + static_assert(std::is_same<decltype(std::any_cast<int const&>(ca)), int const&>::value, ""); + static_assert(std::is_same<decltype(std::any_cast<int const&&>(ca)), int const&&>::value, ""); } template <class Type, class ConstT = Type> -void checkThrows(std::any& a) -{ +void checkThrows(std::any& a) { #if !defined(TEST_HAS_NO_EXCEPTIONS) - try { - TEST_IGNORE_NODISCARD std::any_cast<Type>(a); - assert(false); - } catch (const std::bad_any_cast&) { - // do nothing - } catch (...) { - assert(false); - } - - try { - TEST_IGNORE_NODISCARD std::any_cast<ConstT>(static_cast<const std::any&>(a)); - assert(false); - } catch (const std::bad_any_cast&) { - // do nothing - } catch (...) { - assert(false); - } - - try { - using RefType = typename std::conditional< - std::is_lvalue_reference<Type>::value, - typename std::remove_reference<Type>::type&&, - Type - >::type; - TEST_IGNORE_NODISCARD std::any_cast<RefType>(static_cast<std::any&&>(a)); - assert(false); - } catch (const std::bad_any_cast&) { - // do nothing - } catch (...) { - assert(false); - } + try { + TEST_IGNORE_NODISCARD std::any_cast<Type>(a); + assert(false); + } catch (const std::bad_any_cast&) { + // do nothing + } catch (...) { + assert(false); + } + + try { + TEST_IGNORE_NODISCARD std::any_cast<ConstT>(static_cast<const std::any&>(a)); + assert(false); + } catch (const std::bad_any_cast&) { + // do nothing + } catch (...) { + assert(false); + } + + try { + using RefType = typename std:: + conditional< std::is_lvalue_reference<Type>::value, typename std::remove_reference<Type>::type&&, Type >::type; + TEST_IGNORE_NODISCARD std::any_cast<RefType>(static_cast<std::any&&>(a)); + assert(false); + } catch (const std::bad_any_cast&) { + // do nothing + } catch (...) { + assert(false); + } #else - (TEST_IGNORE_NODISCARD a); + (TEST_IGNORE_NODISCARD a); #endif } void test_cast_empty() { - // None of these operations should allocate. - DisableAllocationGuard g; (TEST_IGNORE_NODISCARD g); - std::any a; - checkThrows<int>(a); + // None of these operations should allocate. + DisableAllocationGuard g; + (TEST_IGNORE_NODISCARD g); + std::any a; + checkThrows<int>(a); } template <class Type> void test_cast_to_reference() { - assert(Type::count == 0); - Type::reset(); + assert(Type::count == 0); + Type::reset(); + { + std::any a = Type(42); + const std::any& ca = a; + assert(Type::count == 1); + assert(Type::copied == 0); + assert(Type::moved == 1); + + // Try a cast to a bad type. + // NOTE: Type cannot be an int. + checkThrows<int>(a); + checkThrows<int&, int const&>(a); + checkThrows<Type*, Type const*>(a); + checkThrows<Type const*>(a); + + // Check getting a type by reference from a non-const lvalue any. + { + Type& v = std::any_cast<Type&>(a); + assert(v.value == 42); + + Type const& cv = std::any_cast<Type const&>(a); + assert(&cv == &v); + } + // Check getting a type by reference from a const lvalue any. { - std::any a = Type(42); - const std::any& ca = a; - assert(Type::count == 1); - assert(Type::copied == 0); - assert(Type::moved == 1); - - // Try a cast to a bad type. - // NOTE: Type cannot be an int. - checkThrows<int>(a); - checkThrows<int&, int const&>(a); - checkThrows<Type*, Type const*>(a); - checkThrows<Type const*>(a); - - // Check getting a type by reference from a non-const lvalue any. - { - Type& v = std::any_cast<Type&>(a); - assert(v.value == 42); - - Type const &cv = std::any_cast<Type const&>(a); - assert(&cv == &v); - } - // Check getting a type by reference from a const lvalue any. - { - Type const& v = std::any_cast<Type const&>(ca); - assert(v.value == 42); - - Type const &cv = std::any_cast<Type const&>(ca); - assert(&cv == &v); - } - // Check getting a type by reference from a const rvalue any. - { - Type const& v = std::any_cast<Type const&>(std::move(ca)); - assert(v.value == 42); - - Type const &cv = std::any_cast<Type const&>(std::move(ca)); - assert(&cv == &v); - } - // Check getting a type by reference from a const rvalue any. - { - Type&& v = std::any_cast<Type&&>(std::move(a)); - assert(v.value == 42); - assert(std::any_cast<Type&>(a).value == 42); - - Type&& cv = std::any_cast<Type&&>(std::move(a)); - assert(&cv == &v); - assert(std::any_cast<Type&>(a).value == 42); - } - // Check getting a type by reference from a const rvalue any. - { - Type const&& v = std::any_cast<Type const&&>(std::move(a)); - assert(v.value == 42); - assert(std::any_cast<Type&>(a).value == 42); - - Type const&& cv = std::any_cast<Type const&&>(std::move(a)); - assert(&cv == &v); - assert(std::any_cast<Type&>(a).value == 42); - } - // Check that the original object hasn't been changed. - assertContains<Type>(a, 42); - - // Check that no objects have been created/copied/moved. - assert(Type::count == 1); - assert(Type::copied == 0); - assert(Type::moved == 1); + Type const& v = std::any_cast<Type const&>(ca); + assert(v.value == 42); + + Type const& cv = std::any_cast<Type const&>(ca); + assert(&cv == &v); } - assert(Type::count == 0); + // Check getting a type by reference from a const rvalue any. + { + Type const& v = std::any_cast<Type const&>(std::move(ca)); + assert(v.value == 42); + + Type const& cv = std::any_cast<Type const&>(std::move(ca)); + assert(&cv == &v); + } + // Check getting a type by reference from a const rvalue any. + { + Type&& v = std::any_cast<Type&&>(std::move(a)); + assert(v.value == 42); + assert(std::any_cast<Type&>(a).value == 42); + + Type&& cv = std::any_cast<Type&&>(std::move(a)); + assert(&cv == &v); + assert(std::any_cast<Type&>(a).value == 42); + } + // Check getting a type by reference from a const rvalue any. + { + Type const&& v = std::any_cast<Type const&&>(std::move(a)); + assert(v.value == 42); + assert(std::any_cast<Type&>(a).value == 42); + + Type const&& cv = std::any_cast<Type const&&>(std::move(a)); + assert(&cv == &v); + assert(std::any_cast<Type&>(a).value == 42); + } + // Check that the original object hasn't been changed. + assertContains<Type>(a, 42); + + // Check that no objects have been created/copied/moved. + assert(Type::count == 1); + assert(Type::copied == 0); + assert(Type::moved == 1); + } + assert(Type::count == 0); } template <class Type> void test_cast_to_value() { - assert(Type::count == 0); + assert(Type::count == 0); + Type::reset(); + { + std::any a = Type(42); + assert(Type::count == 1); + assert(Type::copied == 0); + assert(Type::moved == 1); + + // Try a cast to a bad type. + // NOTE: Type cannot be an int. + checkThrows<int>(a); + checkThrows<int&, int const&>(a); + checkThrows<Type*, Type const*>(a); + checkThrows<Type const*>(a); + + Type::reset(); // NOTE: reset does not modify Type::count + // Check getting Type by value from a non-const lvalue any. + // This should cause the non-const copy constructor to be called. + { + Type t = std::any_cast<Type>(a); + + assert(Type::count == 2); + assert(Type::copied == 1); + assert(Type::const_copied == 0); + assert(Type::non_const_copied == 1); + assert(Type::moved == 0); + assert(t.value == 42); + } + assert(Type::count == 1); + Type::reset(); + // Check getting const Type by value from a non-const lvalue any. + // This should cause the const copy constructor to be called. + { + Type t = std::any_cast<Type const>(a); + + assert(Type::count == 2); + assert(Type::copied == 1); + assert(Type::const_copied == 0); + assert(Type::non_const_copied == 1); + assert(Type::moved == 0); + assert(t.value == 42); + } + assert(Type::count == 1); Type::reset(); + // Check getting Type by value from a non-const lvalue any. + // This should cause the const copy constructor to be called. { - std::any a = Type(42); - assert(Type::count == 1); - assert(Type::copied == 0); - assert(Type::moved == 1); - - // Try a cast to a bad type. - // NOTE: Type cannot be an int. - checkThrows<int>(a); - checkThrows<int&, int const&>(a); - checkThrows<Type*, Type const*>(a); - checkThrows<Type const*>(a); - - Type::reset(); // NOTE: reset does not modify Type::count - // Check getting Type by value from a non-const lvalue any. - // This should cause the non-const copy constructor to be called. - { - Type t = std::any_cast<Type>(a); - - assert(Type::count == 2); - assert(Type::copied == 1); - assert(Type::const_copied == 0); - assert(Type::non_const_copied == 1); - assert(Type::moved == 0); - assert(t.value == 42); - } - assert(Type::count == 1); - Type::reset(); - // Check getting const Type by value from a non-const lvalue any. - // This should cause the const copy constructor to be called. - { - Type t = std::any_cast<Type const>(a); - - assert(Type::count == 2); - assert(Type::copied == 1); - assert(Type::const_copied == 0); - assert(Type::non_const_copied == 1); - assert(Type::moved == 0); - assert(t.value == 42); - } - assert(Type::count == 1); - Type::reset(); - // Check getting Type by value from a non-const lvalue any. - // This should cause the const copy constructor to be called. - { - Type t = std::any_cast<Type>(static_cast<const std::any&>(a)); - - assert(Type::count == 2); - assert(Type::copied == 1); - assert(Type::const_copied == 1); - assert(Type::non_const_copied == 0); - assert(Type::moved == 0); - assert(t.value == 42); - } - assert(Type::count == 1); - Type::reset(); - // Check getting Type by value from a non-const rvalue any. - // This should cause the non-const copy constructor to be called. - { - Type t = std::any_cast<Type>(static_cast<std::any&&>(a)); - - assert(Type::count == 2); - assert(Type::moved == 1); - assert(Type::copied == 0); - assert(Type::const_copied == 0); - assert(Type::non_const_copied == 0); - assert(t.value == 42); - assert(std::any_cast<Type&>(a).value == 0); - std::any_cast<Type&>(a).value = 42; // reset the value - } - assert(Type::count == 1); - Type::reset(); - // Check getting const Type by value from a non-const rvalue any. - // This should cause the const copy constructor to be called. - { - Type t = std::any_cast<Type const>(static_cast<std::any&&>(a)); - - assert(Type::count == 2); - assert(Type::copied == 0); - assert(Type::const_copied == 0); - assert(Type::non_const_copied == 0); - assert(Type::moved == 1); - assert(t.value == 42); - assert(std::any_cast<Type&>(a).value == 0); - std::any_cast<Type&>(a).value = 42; // reset the value - } - assert(Type::count == 1); - Type::reset(); - // Check getting Type by value from a const rvalue any. - // This should cause the const copy constructor to be called. - { - Type t = std::any_cast<Type>(static_cast<const std::any&&>(a)); - - assert(Type::count == 2); - assert(Type::copied == 1); - assert(Type::const_copied == 1); - assert(Type::non_const_copied == 0); - assert(Type::moved == 0); - assert(t.value == 42); - assert(std::any_cast<Type&>(a).value == 42); - } - // Ensure we still only have 1 Type object alive. - assert(Type::count == 1); - - // Check that the original object hasn't been changed. - assertContains<Type>(a, 42); + Type t = std::any_cast<Type>(static_cast<const std::any&>(a)); + + assert(Type::count == 2); + assert(Type::copied == 1); + assert(Type::const_copied == 1); + assert(Type::non_const_copied == 0); + assert(Type::moved == 0); + assert(t.value == 42); } - assert(Type::count == 0); + assert(Type::count == 1); + Type::reset(); + // Check getting Type by value from a non-const rvalue any. + // This should cause the non-const copy constructor to be called. + { + Type t = std::any_cast<Type>(static_cast<std::any&&>(a)); + + assert(Type::count == 2); + assert(Type::moved == 1); + assert(Type::copied == 0); + assert(Type::const_copied == 0); + assert(Type::non_const_copied == 0); + assert(t.value == 42); + assert(std::any_cast<Type&>(a).value == 0); + std::any_cast<Type&>(a).value = 42; // reset the value + } + assert(Type::count == 1); + Type::reset(); + // Check getting const Type by value from a non-const rvalue any. + // This should cause the const copy constructor to be called. + { + Type t = std::any_cast<Type const>(static_cast<std::any&&>(a)); + + assert(Type::count == 2); + assert(Type::copied == 0); + assert(Type::const_copied == 0); + assert(Type::non_const_copied == 0); + assert(Type::moved == 1); + assert(t.value == 42); + assert(std::any_cast<Type&>(a).value == 0); + std::any_cast<Type&>(a).value = 42; // reset the value + } + assert(Type::count == 1); + Type::reset(); + // Check getting Type by value from a const rvalue any. + // This should cause the const copy constructor to be called. + { + Type t = std::any_cast<Type>(static_cast<const std::any&&>(a)); + + assert(Type::count == 2); + assert(Type::copied == 1); + assert(Type::const_copied == 1); + assert(Type::non_const_copied == 0); + assert(Type::moved == 0); + assert(t.value == 42); + assert(std::any_cast<Type&>(a).value == 42); + } + // Ensure we still only have 1 Type object alive. + assert(Type::count == 1); + + // Check that the original object hasn't been changed. + assertContains<Type>(a, 42); + } + assert(Type::count == 0); } int main(int, char**) { - test_cast_is_not_noexcept(); - test_cast_return_type(); - test_cast_empty(); - test_cast_to_reference<small>(); - test_cast_to_reference<large>(); - test_cast_to_value<small>(); - test_cast_to_value<large>(); + test_cast_is_not_noexcept(); + test_cast_return_type(); + test_cast_empty(); + test_cast_to_reference<small>(); + test_cast_to_reference<large>(); + test_cast_to_value<small>(); + test_cast_to_value<large>(); return 0; } diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_request_invalid_value_category.verify.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_request_invalid_value_category.verify.cpp index 34f785fd..55e9923 100644 --- a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_request_invalid_value_category.verify.cpp +++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_request_invalid_value_category.verify.cpp @@ -19,47 +19,35 @@ struct TestType {}; -void test_const_lvalue_cast_request_non_const_lvalue() -{ - const std::any a; - // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}} - // expected-error@any:* {{drops 'const' qualifier}} - std::any_cast<TestType &>(a); // expected-note {{requested here}} - - const std::any a2(42); - // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}} - // expected-error@any:* {{drops 'const' qualifier}} - std::any_cast<int&>(a2); // expected-note {{requested here}} -} - -void test_lvalue_any_cast_request_rvalue() -{ - std::any a; - // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an lvalue reference or a CopyConstructible type}} - std::any_cast<TestType &&>(a); // expected-note {{requested here}} - - std::any a2(42); - // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an lvalue reference or a CopyConstructible type}} - std::any_cast<int&&>(a2); // expected-note {{requested here}} +void test_const_lvalue_cast_request_non_const_lvalue() { + const std::any a; + // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}} + // expected-error@any:* {{drops 'const' qualifier}} + (void)std::any_cast<TestType&>(a); // expected-note {{requested here}} + + const std::any a2(42); + // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}} + // expected-error@any:* {{drops 'const' qualifier}} + (void)std::any_cast<int&>(a2); // expected-note {{requested here}} } -void test_rvalue_any_cast_request_lvalue() -{ - std::any a; - // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an rvalue reference or a CopyConstructible type}} - // expected-error@any:* {{non-const lvalue reference to type 'TestType' cannot bind to a temporary}} - std::any_cast<TestType &>(std::move(a)); // expected-note {{requested here}} +void test_lvalue_any_cast_request_rvalue() { + std::any a; + // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an lvalue reference or a CopyConstructible type}} + (void)std::any_cast<TestType&&>(a); // expected-note {{requested here}} - // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an rvalue reference or a CopyConstructible type}} - // expected-error@any:* {{non-const lvalue reference to type 'int' cannot bind to a temporary}} - std::any_cast<int&>(42); + std::any a2(42); + // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an lvalue reference or a CopyConstructible type}} + (void)std::any_cast<int&&>(a2); // expected-note {{requested here}} } -int main(int, char**) -{ - test_const_lvalue_cast_request_non_const_lvalue(); - test_lvalue_any_cast_request_rvalue(); - test_rvalue_any_cast_request_lvalue(); +void test_rvalue_any_cast_request_lvalue() { + std::any a; + // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an rvalue reference or a CopyConstructible type}} + // expected-error@any:* {{non-const lvalue reference to type 'TestType' cannot bind to a temporary}} + (void)std::any_cast<TestType&>(std::move(a)); // expected-note {{requested here}} - return 0; + // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an rvalue reference or a CopyConstructible type}} + // expected-error@any:* {{non-const lvalue reference to type 'int' cannot bind to a temporary}} + (void)std::any_cast<int&>(42); } diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.verify.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.verify.cpp index 1830626..4ed1692 100644 --- a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.verify.cpp +++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.verify.cpp @@ -27,18 +27,18 @@ struct TestType {}; struct TestType2 {}; -void f() { - std::any a; +void test() { + std::any a; - // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}} - std::any_cast<TestType &>(static_cast<std::any const&>(a)); // expected-note {{requested here}} + // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}} + (void)std::any_cast<TestType&>(static_cast<std::any const&>(a)); // expected-note {{requested here}} - // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}} - std::any_cast<TestType &&>(static_cast<std::any const&>(a)); // expected-note {{requested here}} + // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}} + (void)std::any_cast<TestType&&>(static_cast<std::any const&>(a)); // expected-note {{requested here}} - // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}} - std::any_cast<TestType2 &>(static_cast<std::any const&&>(a)); // expected-note {{requested here}} + // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}} + (void)std::any_cast<TestType2&>(static_cast<std::any const&&>(a)); // expected-note {{requested here}} - // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}} - std::any_cast<TestType2 &&>(static_cast<std::any const&&>(a)); // expected-note {{requested here}} + // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}} + (void)std::any_cast<TestType2&&>(static_cast<std::any const&&>(a)); // expected-note {{requested here}} } diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.verify.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.verify.cpp index 3b9aac5..ad91455 100644 --- a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.verify.cpp +++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.verify.cpp @@ -31,27 +31,27 @@ #include <any> struct no_copy { - no_copy() {} - no_copy(no_copy &&) {} - no_copy(no_copy const &) = delete; + no_copy() {} + no_copy(no_copy&&) {} + no_copy(no_copy const&) = delete; }; struct no_move { - no_move() {} - no_move(no_move&&) = delete; - no_move(no_move const&) {} + no_move() {} + no_move(no_move&&) = delete; + no_move(no_move const&) {} }; -void f() { - std::any a; - // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an lvalue reference or a CopyConstructible type}} - std::any_cast<no_copy>(static_cast<std::any&>(a)); // expected-note {{requested here}} +void test() { + std::any a; + // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an lvalue reference or a CopyConstructible type}} + (void)std::any_cast<no_copy>(static_cast<std::any&>(a)); // expected-note {{requested here}} - // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}} - std::any_cast<no_copy>(static_cast<std::any const&>(a)); // expected-note {{requested here}} + // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be a const lvalue reference or a CopyConstructible type}} + (void)std::any_cast<no_copy>(static_cast<std::any const&>(a)); // expected-note {{requested here}} - std::any_cast<no_copy>(static_cast<std::any &&>(a)); // OK + (void)std::any_cast<no_copy>(static_cast<std::any&&>(a)); // OK - // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an rvalue reference or a CopyConstructible type}} - std::any_cast<no_move>(static_cast<std::any &&>(a)); + // expected-error-re@any:* {{static assertion failed{{.*}}ValueType is required to be an rvalue reference or a CopyConstructible type}} + (void)std::any_cast<no_move>(static_cast<std::any&&>(a)); } diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/reference_types.verify.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/reference_types.verify.cpp index 0a13fdf..d634f73 100644 --- a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/reference_types.verify.cpp +++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/reference_types.verify.cpp @@ -18,35 +18,32 @@ #include <any> -int main(int, char**) -{ - std::any a = 1; +void test() { + std::any a = 1; - // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}} - std::any_cast<int &>(&a); // expected-note {{requested here}} + // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}} + (void)std::any_cast<int&>(&a); // expected-note {{requested here}} - // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}} - std::any_cast<int &&>(&a); // expected-note {{requested here}} + // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}} + (void)std::any_cast<int&&>(&a); // expected-note {{requested here}} - // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}} - std::any_cast<int const &>(&a); // expected-note {{requested here}} + // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}} + (void)std::any_cast<int const&>(&a); // expected-note {{requested here}} - // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}} - std::any_cast<int const&&>(&a); // expected-note {{requested here}} + // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}} + (void)std::any_cast<int const&&>(&a); // expected-note {{requested here}} - const std::any& a2 = a; + const std::any& a2 = a; - // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}} - std::any_cast<int &>(&a2); // expected-note {{requested here}} + // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}} + (void)std::any_cast<int&>(&a2); // expected-note {{requested here}} - // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}} - std::any_cast<int &&>(&a2); // expected-note {{requested here}} + // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}} + (void)std::any_cast<int&&>(&a2); // expected-note {{requested here}} - // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}} - std::any_cast<int const &>(&a2); // expected-note {{requested here}} + // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}} + (void)std::any_cast<int const&>(&a2); // expected-note {{requested here}} - // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}} - std::any_cast<int const &&>(&a2); // expected-note {{requested here}} - - return 0; + // expected-error-re@any:* 1 {{static assertion failed{{.*}}_ValueType may not be a reference.}} + (void)std::any_cast<int const&&>(&a2); // expected-note {{requested here}} } diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/void.verify.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/void.verify.cpp index 9530d63..d1ec42ea 100644 --- a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/void.verify.cpp +++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/void.verify.cpp @@ -23,12 +23,12 @@ void test() { const std::any ca = 1; // expected-error-re@any:* {{static assertion failed{{.*}}_ValueType may not be void.}} - std::any_cast<void>(&ca); // expected-note {{requested here}} + (void)std::any_cast<void>(&ca); // expected-note {{requested here}} } { std::any a = 1; // expected-error-re@any:* {{static assertion failed{{.*}}_ValueType may not be void.}} - std::any_cast<void>(&a); // expected-note {{requested here}} + (void)std::any_cast<void>(&a); // expected-note {{requested here}} } } diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp index 2774401..f666e8b 100644 --- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp @@ -27,23 +27,23 @@ int main(int, char**) { Ptr x = nullptr; const Ptr cx = nullptr; - std::ref(no_args)(); - std::ref(one_arg)(x); - std::ref(one_arg)(cx); - std::ref(two_args)(x, x); - std::ref(two_args)(x, cx); - std::ref(two_args)(cx, x); - std::ref(two_args)(cx, cx); - std::ref(three_args)(x, x, x); - std::ref(three_args)(x, x, cx); - std::ref(three_args)(x, cx, x); - std::ref(three_args)(cx, x, x); - std::ref(three_args)(x, cx, cx); - std::ref(three_args)(cx, x, cx); - std::ref(three_args)(cx, cx, x); - std::ref(three_args)(cx, cx, cx); - std::ref(one_arg_void)(x); - std::ref(one_arg_void)(cx); + (void)std::ref(no_args)(); + (void)std::ref(one_arg)(x); + (void)std::ref(one_arg)(cx); + (void)std::ref(two_args)(x, x); + (void)std::ref(two_args)(x, cx); + (void)std::ref(two_args)(cx, x); + (void)std::ref(two_args)(cx, cx); + (void)std::ref(three_args)(x, x, x); + (void)std::ref(three_args)(x, x, cx); + (void)std::ref(three_args)(x, cx, x); + (void)std::ref(three_args)(cx, x, x); + (void)std::ref(three_args)(x, cx, cx); + (void)std::ref(three_args)(cx, x, cx); + (void)std::ref(three_args)(cx, cx, x); + (void)std::ref(three_args)(cx, cx, cx); + (void)std::ref(one_arg_void)(x); + (void)std::ref(one_arg_void)(cx); return 0; } diff --git a/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/make_obj_using_allocator.pass.cpp b/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/make_obj_using_allocator.pass.cpp index 1f60514..744e530 100644 --- a/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/make_obj_using_allocator.pass.cpp +++ b/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/make_obj_using_allocator.pass.cpp @@ -14,6 +14,7 @@ // test_memory_resource requires RTTI for dynamic_cast // UNSUPPORTED: no-rtti +#include <cassert> #include <concepts> #include <memory> #include <tuple> diff --git a/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uninitialized_construct_using_allocator.pass.cpp b/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uninitialized_construct_using_allocator.pass.cpp index 07260e5..329698c 100644 --- a/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uninitialized_construct_using_allocator.pass.cpp +++ b/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uninitialized_construct_using_allocator.pass.cpp @@ -14,6 +14,7 @@ // test_memory_resource requires RTTI for dynamic_cast // UNSUPPORTED: no-rtti +#include <cassert> #include <concepts> #include <memory> #include <tuple> diff --git a/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uses_allocator_construction_args.pass.cpp b/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uses_allocator_construction_args.pass.cpp index 93a445d7..aa3a5e8 100644 --- a/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uses_allocator_construction_args.pass.cpp +++ b/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.construction/uses_allocator_construction_args.pass.cpp @@ -14,10 +14,12 @@ // test_memory_resource requires RTTI for dynamic_cast // UNSUPPORTED: no-rtti +#include <cassert> #include <concepts> #include <memory> #include <ranges> #include <tuple> +#include <type_traits> #include <utility> #include "common.h" diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp index 9308bb3..f956262 100644 --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp @@ -12,6 +12,8 @@ // template <class Y, class D> shared_ptr(unique_ptr<Y, D>&&r); +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + #include <memory> #include <new> #include <cstdlib> @@ -165,12 +167,10 @@ int main(int, char**) { // LWG 2399 fn(std::unique_ptr<int>(new int)); } -#if TEST_STD_VER >= 14 { // LWG 2415 std::unique_ptr<int, void (*)(int*)> p(nullptr, assert_deleter<int>); std::shared_ptr<int> p2(std::move(p)); // should not call deleter when going out of scope } -#endif { adl::D d; diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/unique.deprecated_in_cxx17.verify.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/unique.deprecated_in_cxx17.verify.cpp index eae0f6e..bc6f2a3 100644 --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/unique.deprecated_in_cxx17.verify.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/unique.deprecated_in_cxx17.verify.cpp @@ -20,5 +20,5 @@ void f() { const std::shared_ptr<int> p; - p.unique(); // expected-warning {{'unique' is deprecated}} + (void)p.unique(); // expected-warning {{'unique' is deprecated}} } diff --git a/libcxx/test/std/utilities/optional/optional.iterator/begin.pass.cpp b/libcxx/test/std/utilities/optional/optional.iterator/begin.pass.cpp index df95a8d..8123452 100644 --- a/libcxx/test/std/utilities/optional/optional.iterator/begin.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.iterator/begin.pass.cpp @@ -21,7 +21,8 @@ template <typename T> constexpr bool test() { - std::optional<T> opt{T{}}; + std::remove_reference_t<T> t = std::remove_reference_t<T>{}; + std::optional<T> opt{t}; { // begin() is marked noexcept static_assert(noexcept(opt.begin())); @@ -53,6 +54,10 @@ constexpr bool tests() { assert(test<char>()); assert(test<const int>()); assert(test<const char>()); + assert(test<int&>()); + assert(test<char&>()); + assert(test<const int&>()); + assert(test<const char&>()); return true; } diff --git a/libcxx/test/std/utilities/optional/optional.iterator/borrowed_range.compile.pass.cpp b/libcxx/test/std/utilities/optional/optional.iterator/borrowed_range.compile.pass.cpp new file mode 100644 index 0000000..a79d1d5 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.iterator/borrowed_range.compile.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++26 + +// <optional> + +// template <class T> class optional<T&>::iterator; +// template <class T> class optional<T&>::const_iterator; +// template <class T> +// constexpr bool ranges::enable_borrowed_range<optional<T&>> = true; + +#include <cassert> +#include <optional> +#include <ranges> + +template <typename T> +void borrowed_range() { + static_assert(std::ranges::enable_borrowed_range<std::optional<T&>>); + static_assert(std::ranges::range<std::optional<T&>> == std::ranges::borrowed_range<std::optional<T&>>); +} + +void test_borrowed_range() { + borrowed_range<int>(); + borrowed_range<const int>(); + borrowed_range<int[]>(); + borrowed_range<int[10]>(); + borrowed_range<int()>(); +} diff --git a/libcxx/test/std/utilities/optional/optional.iterator/end.pass.cpp b/libcxx/test/std/utilities/optional/optional.iterator/end.pass.cpp index 966c3e7..c62c9fc 100644 --- a/libcxx/test/std/utilities/optional/optional.iterator/end.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.iterator/end.pass.cpp @@ -17,6 +17,7 @@ #include <iterator> #include <optional> #include <ranges> +#include <type_traits> #include <utility> template <typename T> @@ -41,7 +42,8 @@ constexpr bool test() { assert(it2 == std::as_const(disengaged).end()); } - std::optional<T> engaged{T{}}; + std::remove_reference_t<T> t = std::remove_reference_t<T>{}; + std::optional<T> engaged{t}; { // end() != begin() if the optional is engaged auto it = engaged.end(); @@ -62,6 +64,10 @@ constexpr bool tests() { assert(test<char>()); assert(test<const int>()); assert(test<const char>()); + assert(test<int&>()); + assert(test<char&>()); + assert(test<const int&>()); + assert(test<const char&>()); return true; } diff --git a/libcxx/test/std/utilities/optional/optional.iterator/iterator.pass.cpp b/libcxx/test/std/utilities/optional/optional.iterator/iterator.pass.cpp index 1203290..671fac3 100644 --- a/libcxx/test/std/utilities/optional/optional.iterator/iterator.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.iterator/iterator.pass.cpp @@ -14,15 +14,23 @@ // template <class T> class optional::const_iterator; #include <cassert> -#include <iterator> #include <optional> #include <ranges> #include <type_traits> #include <utility> -template <typename T, T __val> +template <typename T> +constexpr bool test_range_concept() { + return std::ranges::range<std::optional<T>>; +} + +template <typename T, std::remove_reference_t<T> __val> constexpr bool test() { - std::optional<T> opt{__val}; + std::remove_reference_t<T> v{__val}; + std::optional<T> opt{v}; + { + assert(test_range_concept<T>()); + } { // Dereferencing an iterator of an engaged optional will return the same value that the optional holds. auto it = opt.begin(); @@ -41,13 +49,14 @@ constexpr bool test() { assert(std::random_access_iterator<decltype(it2)>); } - { // const_iterator::value_type == std::remove_cv_t<T>, const_iterator::reference == const T&, iterator::value_type = std::remove_cv_t<T>, iterator::reference == T& + { // const_iterator::value_type == std::remove_cvref_t<T>, const_iterator::reference == const T&, iterator::value_type = std::remove_cvref_t<T>, iterator::reference == T& + // std::remove_cv_t is impossible for optional<T&> auto it = opt.begin(); auto it2 = std::as_const(opt).begin(); - assert((std::is_same_v<typename decltype(it)::value_type, std::remove_cv_t<T>>)); - assert((std::is_same_v<typename decltype(it)::reference, T&>)); - assert((std::is_same_v<typename decltype(it2)::value_type, std::remove_cv_t<T>>)); - assert((std::is_same_v<typename decltype(it2)::reference, const T&>)); + assert((std::is_same_v<typename decltype(it)::value_type, std::remove_cvref_t<T>>)); + assert((std::is_same_v<typename decltype(it)::reference, std::remove_reference_t<T>&>)); + assert((std::is_same_v<typename decltype(it2)::value_type, std::remove_cvref_t<T>>)); + assert((std::is_same_v<typename decltype(it2)::reference, const std::remove_reference_t<T>&>)); } { // std::ranges::size for an engaged optional<T> == 1, disengaged optional<T> == 0 @@ -68,13 +77,13 @@ constexpr bool test() { // An optional with value that is reset will have a begin() == end(), then when it is reassigned a value, // begin() != end(), and *begin() will contain the new value. { - std::optional<T> val{__val}; + std::optional<T> val{v}; assert(val.begin() != val.end()); val.reset(); assert(val.begin() == val.end()); - val.emplace(__val); + val.emplace(v); assert(val.begin() != val.end()); - assert(*(val.begin()) == __val); + assert(*(val.begin()) == v); } return true; @@ -86,6 +95,15 @@ constexpr bool tests() { assert((test<bool, true>())); assert((test<const int, 2>())); assert((test<const char, 'b'>())); + assert((test<int&, 1>())); + assert((test<char&, 'a'>())); + assert((test<bool&, true>())); + assert((test<const int&, 2>())); + assert((test<const char&, 'b'>())); + + assert(!test_range_concept<int (&)()>()); + assert(!test_range_concept<int (&)[]>()); + assert(!test_range_concept<int (&)[42]>()); return true; } diff --git a/libcxx/test/std/utilities/optional/optional.monadic/and_then.pass.cpp b/libcxx/test/std/utilities/optional/optional.monadic/and_then.pass.cpp index 97305d9..133eed4 100644 --- a/libcxx/test/std/utilities/optional/optional.monadic/and_then.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.monadic/and_then.pass.cpp @@ -16,6 +16,7 @@ // template<class F> constexpr auto and_then(F&&) const&&; #include <cassert> +#include <concepts> #include <optional> #include "test_macros.h" @@ -257,8 +258,94 @@ constexpr bool test() { return true; } +#if TEST_STD_VER >= 26 +constexpr bool test_ref() { + // Test & overload + { + // Without & qualifier on F's operator() + { + int j = 42; + std::optional<int&> i{j}; + std::same_as<std::optional<int>> decltype(auto) r = i.and_then(LVal{}); + + assert(r == 1); + assert(i.and_then(NOLVal{}) == std::nullopt); + } + + //With & qualifier on F's operator() + { + int j = 42; + std::optional<int&> i{j}; + RefQual l{}; + NORefQual nl{}; + std::same_as<std::optional<int>> decltype(auto) r = i.and_then(l); + + assert(r == 1); + assert(i.and_then(nl) == std::nullopt); + } + } + + // Test const& overload + { + // Without & qualifier on F's operator() + { + int j = 42; + std::optional<const int&> i{j}; + std::same_as<std::optional<int>> decltype(auto) r = i.and_then(CLVal{}); + + assert(r == 1); + assert(i.and_then(NOCLVal{}) == std::nullopt); + } + + //With & qualifier on F's operator() + { + int j = 42; + const std::optional<int&> i{j}; + const CRefQual l{}; + const NOCRefQual nl{}; + std::same_as<std::optional<int>> decltype(auto) r = i.and_then(l); + + assert(r == 1); + assert(i.and_then(nl) == std::nullopt); + } + } + // Test && overload + { + //With & qualifier on F's operator() + { + int j = 42; + std::optional<int&> i{j}; + std::same_as<std::optional<int>> decltype(auto) r = i.and_then(RVRefQual{}); + + assert(r == 1); + assert(i.and_then(NORVRefQual{}) == std::nullopt); + } + } + + // Test const&& overload + { + //With & qualifier on F's operator() + { + int j = 42; + const std::optional<int&> i{j}; + const RVCRefQual l{}; + const NORVCRefQual nl{}; + std::same_as<std::optional<int>> decltype(auto) r = i.and_then(std::move(l)); + + assert(r == 1); + assert(i.and_then(std::move(nl)) == std::nullopt); + } + } + return true; +} +#endif + int main(int, char**) { test(); static_assert(test()); +#if TEST_STD_VER >= 26 + test_ref(); + static_assert(test_ref()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.monadic/or_else.pass.cpp b/libcxx/test/std/utilities/optional/optional.monadic/or_else.pass.cpp index ccc94ab..de0a67c 100644 --- a/libcxx/test/std/utilities/optional/optional.monadic/or_else.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.monadic/or_else.pass.cpp @@ -62,6 +62,32 @@ constexpr bool test() { return std::optional<MoveOnly>{}; }); } +#if TEST_STD_VER >= 26 + { + int i = 2; + std::optional<int&> opt; + assert(opt.or_else([&] { return std::optional<int&>{i}; }) == i); + int j = 3; + opt = j; + opt.or_else([] { + assert(false); + return std::optional<int&>{}; + }); + assert(opt == j); + } + { + int i = 2; + std::optional<int&> opt; + assert(std::move(opt).or_else([&] { return std::optional<int&>{i}; }) == i); + int j = 3; + opt = j; + std::move(opt).or_else([] { + assert(false); + return std::optional<int&>{}; + }); + assert(opt == j); + } +#endif return true; } diff --git a/libcxx/test/std/utilities/optional/optional.monadic/transform.pass.cpp b/libcxx/test/std/utilities/optional/optional.monadic/transform.pass.cpp index 0a15151..ad2713f 100644 --- a/libcxx/test/std/utilities/optional/optional.monadic/transform.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.monadic/transform.pass.cpp @@ -17,62 +17,64 @@ #include "test_macros.h" #include <cassert> +#include <concepts> #include <optional> #include <type_traits> +#include <utility> struct LVal { constexpr int operator()(int&) { return 1; } - int operator()(const int&) = delete; - int operator()(int&&) = delete; + int operator()(const int&) = delete; + int operator()(int&&) = delete; int operator()(const int&&) = delete; }; struct CLVal { int operator()(int&) = delete; constexpr int operator()(const int&) { return 1; } - int operator()(int&&) = delete; + int operator()(int&&) = delete; int operator()(const int&&) = delete; }; struct RVal { - int operator()(int&) = delete; + int operator()(int&) = delete; int operator()(const int&) = delete; constexpr int operator()(int&&) { return 1; } int operator()(const int&&) = delete; }; struct CRVal { - int operator()(int&) = delete; + int operator()(int&) = delete; int operator()(const int&) = delete; - int operator()(int&&) = delete; + int operator()(int&&) = delete; constexpr int operator()(const int&&) { return 1; } }; struct RefQual { constexpr int operator()(int) & { return 1; } - int operator()(int) const& = delete; - int operator()(int) && = delete; + int operator()(int) const& = delete; + int operator()(int) && = delete; int operator()(int) const&& = delete; }; struct CRefQual { int operator()(int) & = delete; constexpr int operator()(int) const& { return 1; } - int operator()(int) && = delete; + int operator()(int) && = delete; int operator()(int) const&& = delete; }; struct RVRefQual { - int operator()(int) & = delete; + int operator()(int) & = delete; int operator()(int) const& = delete; constexpr int operator()(int) && { return 1; } int operator()(int) const&& = delete; }; struct RVCRefQual { - int operator()(int) & = delete; + int operator()(int) & = delete; int operator()(int) const& = delete; - int operator()(int) && = delete; + int operator()(int) && = delete; constexpr int operator()(int) const&& { return 1; } }; @@ -83,7 +85,7 @@ struct NoCopy { }; struct NoMove { - NoMove() = default; + NoMove() = default; NoMove(NoMove&&) = delete; NoMove operator()(const NoCopy&&) { return NoMove{}; } }; @@ -200,8 +202,111 @@ constexpr bool test() { return true; } +#if TEST_STD_VER >= 26 +constexpr bool test_ref() { + { + std::optional<int&> opt1; + std::same_as<std::optional<int>> decltype(auto) opt1r = opt1.transform([](int i) { return i + 2; }); + assert(!opt1); + assert(!opt1r); + } + + { + int i = 42; + std::optional<int&> opt{i}; + std::same_as<std::optional<int>> decltype(auto) o2 = opt.transform([](int j) { return j + 2; }); + + assert(*o2 == 44); + } + // Test & overload + { + // Without & qualifier on F's operator() + { + int i = 42; + std::optional<int&> opt{i}; + std::same_as<std::optional<int>> decltype(auto) o3 = opt.transform(LVal{}); + + assert(*o3 == 1); + } + + //With & qualifier on F's operator() + { + int i = 42; + std::optional<int&> opt{i}; + RefQual l{}; + std::same_as<std::optional<int>> decltype(auto) o3 = opt.transform(l); + + assert(*o3 == 1); + } + } + // const& overload + { + // Without & qualifier on F's operator() + { + int i = 42; + std::optional<const int&> opt{i}; + std::same_as<std::optional<int>> decltype(auto) o3 = std::as_const(opt).transform(CLVal{}); + + assert(*o3 == 1); + } + + //With & qualifier on F's operator() + { + int i = 42; + const std::optional<int&> opt{i}; + const CRefQual l{}; + std::same_as<std::optional<int>> decltype(auto) o3 = opt.transform(l); + + assert(*o3 == 1); + } + } + + // Test && overload + { + // Without & qualifier on F's operator() + { + int i = 42; + std::optional<int> opt{i}; + std::same_as<std::optional<int>> decltype(auto) o3 = std::move(opt).transform(RVal{}); + + assert(*o3 == 1); + } + + //With & qualifier on F's operator() + { + int i = 42; + std::optional<int&> opt{i}; + std::same_as<std::optional<int>> decltype(auto) o3 = std::move(opt).transform(RVRefQual{}); + assert(*o3 == 1); + } + } + + // const&& overload + { + //With & qualifier on F's operator() + { + int i = 42; + std::optional<int&> opt{i}; + const RVCRefQual rvc{}; + std::same_as<std::optional<int>> decltype(auto) o3 = opt.transform(std::move(rvc)); + assert(*o3 == 1); + } + } + { + std::optional<int&> o6 = std::nullopt; + auto o6r = o6.transform([](int) { return 42; }); + assert(!o6r); + } + return true; +} +#endif + int main(int, char**) { test(); static_assert(test()); +#if TEST_STD_VER >= 26 + test_ref(); + static_assert(test_ref()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp index eaca111b..ddb9ffc 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp @@ -250,6 +250,57 @@ constexpr T pr38638(T v) return *o + 2; } +#if TEST_STD_VER >= 26 + +template <typename T, std::remove_reference_t<T> _Val> +constexpr void test_with_ref() { + T t{_Val}; + { // to empty + optional<T&> opt; + opt = t; + assert(static_cast<bool>(opt) == true); + assert(*opt == t); + } + { // to existing + optional<T&> opt{t}; + opt = t; + assert(static_cast<bool>(opt) == true); + assert(*opt == t); + } + { // test default argument + optional<T&> opt; + opt = {t}; + assert(static_cast<bool>(opt) == true); + assert(*opt == t); + } + { // test default argument + optional<T&> opt{t}; + opt = {}; + assert(static_cast<bool>(opt) == false); + } + // test two objects, make sure that the optional only changes what it holds a reference to + { + T t2{_Val}; + optional<T&> opt{t}; + opt = t2; + + assert(std::addressof(*opt) != std::addressof(t)); + assert(std::addressof(*opt) == std::addressof(t2)); + } + // test that reassigning the reference for an optional<T&> doesn't affect the objet it's holding a reference to + { + int i = -1; + int j = 2; + optional<int&> opt{i}; + opt = j; + + assert(i == -1); + assert(std::addressof(*opt) != std::addressof(i)); + assert(std::addressof(*opt) == std::addressof(j)); + assert(*opt == 2); + } +} +#endif int main(int, char**) { @@ -281,5 +332,8 @@ int main(int, char**) static_assert(pr38638(3) == 5, ""); - return 0; +#if TEST_STD_VER >= 26 + test_with_ref<int, 3>(); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp index 245d8ff..629e315 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp @@ -221,6 +221,24 @@ TEST_CONSTEXPR_CXX20 bool test_empty_emplace() { return true; } +#if TEST_STD_VER >= 26 +template <class T, std::remove_reference_t<T> _Val> +constexpr bool test_ref() { + using Opt = std::optional<T&>; + T t{_Val}; + { + Opt opt; + auto& v = opt.emplace(t); + static_assert(std::is_same_v<T&, decltype(v)>); + assert(static_cast<bool>(opt) == true); + assert(*opt == t); + assert(&v == &*opt); + assert(&t == &*opt); + } + return true; +} +#endif + int main(int, char**) { { @@ -291,6 +309,11 @@ int main(int, char**) } } #endif - - return 0; +#if TEST_STD_VER >= 26 + static_assert(test_ref<int, 1>()); + static_assert(test_ref<double, 15.0>()); + assert((test_ref<int, 1>())); + assert((test_ref<double, 15.0>())); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp index a90fecfd..1e951eb 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp @@ -13,25 +13,28 @@ // template <class U> // constexpr EXPLICIT optional(U&& u); +#include <cassert> #include <optional> #include <type_traits> -#include <cassert> #include "test_macros.h" #include "archetypes.h" #include "test_convertible.h" - using std::optional; -struct ImplicitThrow -{ - constexpr ImplicitThrow(int x) { if (x != -1) TEST_THROW(6);} +struct ImplicitThrow { + constexpr ImplicitThrow(int x) { + if (x != -1) + TEST_THROW(6); + } }; -struct ExplicitThrow -{ - constexpr explicit ExplicitThrow(int x) { if (x != -1) TEST_THROW(6);} +struct ExplicitThrow { + constexpr explicit ExplicitThrow(int x) { + if (x != -1) + TEST_THROW(6); + } }; struct ImplicitAny { @@ -39,56 +42,52 @@ struct ImplicitAny { constexpr ImplicitAny(U&&) {} }; - template <class To, class From> -constexpr bool implicit_conversion(optional<To>&& opt, const From& v) -{ - using O = optional<To>; - static_assert(test_convertible<O, From>(), ""); - static_assert(!test_convertible<O, void*>(), ""); - static_assert(!test_convertible<O, From, int>(), ""); - return opt && *opt == static_cast<To>(v); +constexpr bool implicit_conversion(optional<To>&& opt, const From& v) { + using O = optional<To>; + static_assert(test_convertible<O, From>(), ""); + static_assert(!test_convertible<O, void*>(), ""); + static_assert(!test_convertible<O, From, int>(), ""); + return opt && *opt == static_cast<To>(v); } template <class To, class Input, class Expect> -constexpr bool explicit_conversion(Input&& in, const Expect& v) -{ - using O = optional<To>; - static_assert(std::is_constructible<O, Input>::value, ""); - static_assert(!std::is_convertible<Input, O>::value, ""); - static_assert(!std::is_constructible<O, void*>::value, ""); - static_assert(!std::is_constructible<O, Input, int>::value, ""); - optional<To> opt(std::forward<Input>(in)); - optional<To> opt2{std::forward<Input>(in)}; - return opt && *opt == static_cast<To>(v) && (opt2 && *opt2 == static_cast<To>(v)); +constexpr bool explicit_conversion(Input&& in, const Expect& v) { + using O = optional<To>; + static_assert(std::is_constructible<O, Input>::value, ""); + static_assert(!std::is_convertible<Input, O>::value, ""); + static_assert(!std::is_constructible<O, void*>::value, ""); + static_assert(!std::is_constructible<O, Input, int>::value, ""); + optional<To> opt(std::forward<Input>(in)); + optional<To> opt2{std::forward<Input>(in)}; + return opt && *opt == static_cast<To>(v) && (opt2 && *opt2 == static_cast<To>(v)); } -void test_implicit() -{ - { - static_assert(implicit_conversion<long long>(42, 42), ""); - } - { - static_assert(implicit_conversion<long double>(3.14, 3.14), ""); - } - { - int x = 42; - optional<void* const> o(&x); - assert(*o == &x); - } - { - using T = TrivialTestTypes::TestType; - static_assert(implicit_conversion<T>(42, 42), ""); - } - { - using T = TestTypes::TestType; - assert(implicit_conversion<T>(3, T(3))); - } - { - using T = TestTypes::TestType; - optional<T> opt({3}); - assert(opt && *opt == static_cast<T>(3)); - } +void test_implicit() { + { + static_assert(implicit_conversion<long long>(42, 42), ""); + } + { + static_assert(implicit_conversion<long double>(3.14, 3.14), ""); + } + { + int x = 42; + optional<void* const> o(&x); + assert(*o == &x); + } + { + using T = TrivialTestTypes::TestType; + static_assert(implicit_conversion<T>(42, 42), ""); + } + { + using T = TestTypes::TestType; + assert(implicit_conversion<T>(3, T(3))); + } + { + using T = TestTypes::TestType; + optional<T> opt({3}); + assert(opt && *opt == static_cast<T>(3)); + } { using O = optional<ImplicitAny>; static_assert(!test_convertible<O, std::in_place_t>(), ""); @@ -96,64 +95,63 @@ void test_implicit() static_assert(!test_convertible<O, const std::in_place_t&>(), ""); static_assert(!test_convertible<O, std::in_place_t&&>(), ""); static_assert(!test_convertible<O, const std::in_place_t&&>(), ""); - } #ifndef TEST_HAS_NO_EXCEPTIONS - { - try { - using T = ImplicitThrow; - optional<T> t = 42; - assert(false); - ((void)t); - } catch (int) { - } + { + try { + using T = ImplicitThrow; + optional<T> t = 42; + assert(false); + ((void)t); + } catch (int) { } + } #endif } void test_explicit() { + { + using T = ExplicitTrivialTestTypes::TestType; + static_assert(explicit_conversion<T>(42, 42), ""); + } + { + using T = ExplicitConstexprTestTypes::TestType; + static_assert(explicit_conversion<T>(42, 42), ""); + static_assert(!std::is_convertible<int, T>::value, ""); + } + { + using T = ExplicitTestTypes::TestType; + T::reset(); { - using T = ExplicitTrivialTestTypes::TestType; - static_assert(explicit_conversion<T>(42, 42), ""); - } - { - using T = ExplicitConstexprTestTypes::TestType; - static_assert(explicit_conversion<T>(42, 42), ""); - static_assert(!std::is_convertible<int, T>::value, ""); + assert(explicit_conversion<T>(42, 42)); + assert(T::alive == 0); } + T::reset(); { - using T = ExplicitTestTypes::TestType; - T::reset(); - { - assert(explicit_conversion<T>(42, 42)); - assert(T::alive == 0); - } - T::reset(); - { - optional<T> t(42); - assert(T::alive == 1); - assert(T::value_constructed == 1); - assert(T::move_constructed == 0); - assert(T::copy_constructed == 0); - assert(t.value().value == 42); - } - assert(T::alive == 0); + optional<T> t(42); + assert(T::alive == 1); + assert(T::value_constructed == 1); + assert(T::move_constructed == 0); + assert(T::copy_constructed == 0); + assert(t.value().value == 42); } + assert(T::alive == 0); + } #ifndef TEST_HAS_NO_EXCEPTIONS - { - try { - using T = ExplicitThrow; - optional<T> t(42); - assert(false); - } catch (int) { - } + { + try { + using T = ExplicitThrow; + optional<T> t(42); + assert(false); + } catch (int) { } + } #endif } int main(int, char**) { - test_implicit(); - test_explicit(); + test_implicit(); + test_explicit(); return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp index 91a2323..67d0fcf 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp @@ -12,117 +12,102 @@ // constexpr optional(const T& v); +#include <cassert> #include <optional> #include <type_traits> -#include <cassert> #include "test_macros.h" #include "archetypes.h" using std::optional; -int main(int, char**) -{ - { - typedef int T; - constexpr T t(5); - constexpr optional<T> opt(t); - static_assert(static_cast<bool>(opt) == true, ""); - static_assert(*opt == 5, ""); - - struct test_constexpr_ctor - : public optional<T> - { - constexpr test_constexpr_ctor(const T&) {} - }; - - } - { - typedef double T; - constexpr T t(3); - constexpr optional<T> opt(t); - static_assert(static_cast<bool>(opt) == true, ""); - static_assert(*opt == 3, ""); - - struct test_constexpr_ctor - : public optional<T> - { - constexpr test_constexpr_ctor(const T&) {} - }; +int main(int, char**) { + { + typedef int T; + constexpr T t(5); + constexpr optional<T> opt(t); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == 5, ""); - } - { - const int x = 42; - optional<const int> o(x); - assert(*o == x); - } - { - typedef TestTypes::TestType T; - T::reset(); - const T t(3); - optional<T> opt = t; - assert(T::alive == 2); - assert(T::copy_constructed == 1); - assert(static_cast<bool>(opt) == true); - assert(opt.value().value == 3); - } - { - typedef ExplicitTestTypes::TestType T; - static_assert(!std::is_convertible<T const&, optional<T>>::value, ""); - T::reset(); - const T t(3); - optional<T> opt(t); - assert(T::alive == 2); - assert(T::copy_constructed == 1); - assert(static_cast<bool>(opt) == true); - assert(opt.value().value == 3); - } - { - typedef ConstexprTestTypes::TestType T; - constexpr T t(3); - constexpr optional<T> opt = {t}; - static_assert(static_cast<bool>(opt) == true, ""); - static_assert(opt.value().value == 3, ""); + struct test_constexpr_ctor : public optional<T> { + constexpr test_constexpr_ctor(const T&) {} + }; + } + { + typedef double T; + constexpr T t(3); + constexpr optional<T> opt(t); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == 3, ""); - struct test_constexpr_ctor - : public optional<T> - { - constexpr test_constexpr_ctor(const T&) {} - }; - } - { - typedef ExplicitConstexprTestTypes::TestType T; - static_assert(!std::is_convertible<const T&, optional<T>>::value, ""); - constexpr T t(3); - constexpr optional<T> opt(t); - static_assert(static_cast<bool>(opt) == true, ""); - static_assert(opt.value().value == 3, ""); + struct test_constexpr_ctor : public optional<T> { + constexpr test_constexpr_ctor(const T&) {} + }; + } + { + const int x = 42; + optional<const int> o(x); + assert(*o == x); + } + { + typedef TestTypes::TestType T; + T::reset(); + const T t(3); + optional<T> opt = t; + assert(T::alive == 2); + assert(T::copy_constructed == 1); + assert(static_cast<bool>(opt) == true); + assert(opt.value().value == 3); + } + { + typedef ExplicitTestTypes::TestType T; + static_assert(!std::is_convertible<T const&, optional<T>>::value, ""); + T::reset(); + const T t(3); + optional<T> opt(t); + assert(T::alive == 2); + assert(T::copy_constructed == 1); + assert(static_cast<bool>(opt) == true); + assert(opt.value().value == 3); + } + { + typedef ConstexprTestTypes::TestType T; + constexpr T t(3); + constexpr optional<T> opt = {t}; + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(opt.value().value == 3, ""); - struct test_constexpr_ctor - : public optional<T> - { - constexpr test_constexpr_ctor(const T&) {} - }; + struct test_constexpr_ctor : public optional<T> { + constexpr test_constexpr_ctor(const T&) {} + }; + } + { + typedef ExplicitConstexprTestTypes::TestType T; + static_assert(!std::is_convertible<const T&, optional<T>>::value, ""); + constexpr T t(3); + constexpr optional<T> opt(t); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(opt.value().value == 3, ""); - } + struct test_constexpr_ctor : public optional<T> { + constexpr test_constexpr_ctor(const T&) {} + }; + } #ifndef TEST_HAS_NO_EXCEPTIONS - { - struct Z { - Z(int) {} - Z(const Z&) {throw 6;} - }; - typedef Z T; - try - { - const T t(3); - optional<T> opt(t); - assert(false); - } - catch (int i) - { - assert(i == 6); - } + { + struct Z { + Z(int) {} + Z(const Z&) { throw 6; } + }; + typedef Z T; + try { + const T t(3); + optional<T> opt(t); + assert(false); + } catch (int i) { + assert(i == 6); } + } #endif return 0; diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp index 9505238..70fd76e 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp @@ -12,74 +12,69 @@ // template <class U> // optional(const optional<U>& rhs); +#include <cassert> #include <optional> #include <type_traits> -#include <cassert> #include "test_macros.h" using std::optional; template <class T, class U> -TEST_CONSTEXPR_CXX20 void -test(const optional<U>& rhs, bool is_going_to_throw = false) -{ - bool rhs_engaged = static_cast<bool>(rhs); +TEST_CONSTEXPR_CXX20 void test(const optional<U>& rhs, bool is_going_to_throw = false) { + bool rhs_engaged = static_cast<bool>(rhs); #ifndef TEST_HAS_NO_EXCEPTIONS - try - { - optional<T> lhs = rhs; - assert(is_going_to_throw == false); - assert(static_cast<bool>(lhs) == rhs_engaged); - if (rhs_engaged) - assert(*lhs == *rhs); - } - catch (int i) - { - assert(i == 6); - } -#else - if (is_going_to_throw) return; + try { optional<T> lhs = rhs; + assert(is_going_to_throw == false); assert(static_cast<bool>(lhs) == rhs_engaged); if (rhs_engaged) - assert(*lhs == *rhs); + assert(*lhs == *rhs); + } catch (int i) { + assert(i == 6); + } +#else + if (is_going_to_throw) + return; + optional<T> lhs = rhs; + assert(static_cast<bool>(lhs) == rhs_engaged); + if (rhs_engaged) + assert(*lhs == *rhs); #endif } -class X -{ - int i_; +class X { + int i_; + public: - constexpr X(int i) : i_(i) {} - constexpr X(const X& x) : i_(x.i_) {} - TEST_CONSTEXPR_CXX20 ~X() {i_ = 0;} - friend constexpr bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} + constexpr X(int i) : i_(i) {} + constexpr X(const X& x) : i_(x.i_) {} + TEST_CONSTEXPR_CXX20 ~X() { i_ = 0; } + friend constexpr bool operator==(const X& x, const X& y) { return x.i_ == y.i_; } }; -class Y -{ - int i_; +class Y { + int i_; + public: - constexpr Y(int i) : i_(i) {} + constexpr Y(int i) : i_(i) {} - friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;} + friend constexpr bool operator==(const Y& x, const Y& y) { return x.i_ == y.i_; } }; int count = 0; -class Z -{ - int i_; +class Z { + int i_; + public: - Z(int i) : i_(i) {TEST_THROW(6);} + Z(int i) : i_(i) { TEST_THROW(6); } - friend bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;} + friend bool operator==(const Z& x, const Z& y) { return x.i_ == y.i_; } }; -template<class T, class U> -constexpr bool test_all() -{ +template <class T, class U> +constexpr bool test_all() { { optional<U> rhs; test<T>(rhs); @@ -91,30 +86,29 @@ constexpr bool test_all() return true; } -int main(int, char**) -{ - test_all<int, short>(); - test_all<X, int>(); - test_all<Y, int>(); +int main(int, char**) { + test_all<int, short>(); + test_all<X, int>(); + test_all<Y, int>(); #if TEST_STD_VER > 17 - static_assert(test_all<int, short>()); - static_assert(test_all<X, int>()); - static_assert(test_all<Y, int>()); + static_assert(test_all<int, short>()); + static_assert(test_all<X, int>()); + static_assert(test_all<Y, int>()); #endif - { - typedef Z T; - typedef int U; - optional<U> rhs; - test<T>(rhs); - } - { - typedef Z T; - typedef int U; - optional<U> rhs(U{3}); - test<T>(rhs, true); - } - - static_assert(!(std::is_constructible<optional<X>, const optional<Y>&>::value), ""); + { + typedef Z T; + typedef int U; + optional<U> rhs; + test<T>(rhs); + } + { + typedef Z T; + typedef int U; + optional<U> rhs(U{3}); + test<T>(rhs, true); + } + + static_assert(!(std::is_constructible<optional<X>, const optional<Y>&>::value), ""); return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp index 54a424c..f61a22c 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp @@ -11,173 +11,165 @@ // constexpr optional(const optional<T>& rhs); +#include <cassert> #include <optional> #include <type_traits> -#include <cassert> #include "test_macros.h" #include "archetypes.h" using std::optional; -template <class T, class ...InitArgs> -void test(InitArgs&&... args) -{ - const optional<T> rhs(std::forward<InitArgs>(args)...); - bool rhs_engaged = static_cast<bool>(rhs); - optional<T> lhs = rhs; - assert(static_cast<bool>(lhs) == rhs_engaged); - if (rhs_engaged) - assert(*lhs == *rhs); +template <class T, class... InitArgs> +void test(InitArgs&&... args) { + const optional<T> rhs(std::forward<InitArgs>(args)...); + bool rhs_engaged = static_cast<bool>(rhs); + optional<T> lhs = rhs; + assert(static_cast<bool>(lhs) == rhs_engaged); + if (rhs_engaged) + assert(*lhs == *rhs); } -template <class T, class ...InitArgs> -constexpr bool constexpr_test(InitArgs&&... args) -{ - static_assert( std::is_trivially_copy_constructible_v<T>, ""); // requirement - const optional<T> rhs(std::forward<InitArgs>(args)...); - optional<T> lhs = rhs; - return (lhs.has_value() == rhs.has_value()) && - (lhs.has_value() ? *lhs == *rhs : true); +template <class T, class... InitArgs> +constexpr bool constexpr_test(InitArgs&&... args) { + static_assert(std::is_trivially_copy_constructible_v<T>, ""); // requirement + const optional<T> rhs(std::forward<InitArgs>(args)...); + optional<T> lhs = rhs; + return (lhs.has_value() == rhs.has_value()) && (lhs.has_value() ? *lhs == *rhs : true); } void test_throwing_ctor() { #ifndef TEST_HAS_NO_EXCEPTIONS - struct Z { - Z() : count(0) {} - Z(Z const& o) : count(o.count + 1) - { if (count == 2) throw 6; } - int count; - }; - const Z z; - const optional<Z> rhs(z); - try - { - optional<Z> lhs(rhs); - assert(false); - } - catch (int i) - { - assert(i == 6); + struct Z { + Z() : count(0) {} + Z(Z const& o) : count(o.count + 1) { + if (count == 2) + throw 6; } + int count; + }; + const Z z; + const optional<Z> rhs(z); + try { + optional<Z> lhs(rhs); + assert(false); + } catch (int i) { + assert(i == 6); + } #endif } -template <class T, class ...InitArgs> -void test_ref(InitArgs&&... args) -{ - const optional<T> rhs(std::forward<InitArgs>(args)...); - bool rhs_engaged = static_cast<bool>(rhs); - optional<T> lhs = rhs; - assert(static_cast<bool>(lhs) == rhs_engaged); - if (rhs_engaged) - assert(&(*lhs) == &(*rhs)); +template <class T, class... InitArgs> +void test_ref(InitArgs&&... args) { + const optional<T> rhs(std::forward<InitArgs>(args)...); + bool rhs_engaged = static_cast<bool>(rhs); + optional<T> lhs = rhs; + assert(static_cast<bool>(lhs) == rhs_engaged); + if (rhs_engaged) + assert(&(*lhs) == &(*rhs)); } - -void test_reference_extension() -{ +void test_reference_extension() { #if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled. - using T = TestTypes::TestType; - T::reset(); - { - T t; - T::reset_constructors(); - test_ref<T&>(); - test_ref<T&>(t); - assert(T::alive == 1); - assert(T::constructed == 0); - assert(T::assigned == 0); - assert(T::destroyed == 0); - } - assert(T::destroyed == 1); - assert(T::alive == 0); - { - T t; - const T& ct = t; - T::reset_constructors(); - test_ref<T const&>(); - test_ref<T const&>(t); - test_ref<T const&>(ct); - assert(T::alive == 1); - assert(T::constructed == 0); - assert(T::assigned == 0); - assert(T::destroyed == 0); - } - assert(T::alive == 0); - assert(T::destroyed == 1); - { - static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, ""); - static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, ""); - } + using T = TestTypes::TestType; + T::reset(); + { + T t; + T::reset_constructors(); + test_ref<T&>(); + test_ref<T&>(t); + assert(T::alive == 1); + assert(T::constructed == 0); + assert(T::assigned == 0); + assert(T::destroyed == 0); + } + assert(T::destroyed == 1); + assert(T::alive == 0); + { + T t; + const T& ct = t; + T::reset_constructors(); + test_ref<T const&>(); + test_ref<T const&>(t); + test_ref<T const&>(ct); + assert(T::alive == 1); + assert(T::constructed == 0); + assert(T::assigned == 0); + assert(T::destroyed == 0); + } + assert(T::alive == 0); + assert(T::destroyed == 1); + { + static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, ""); + static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, ""); + } #endif } -int main(int, char**) -{ - test<int>(); - test<int>(3); - static_assert(constexpr_test<int>(), "" ); - static_assert(constexpr_test<int>(3), "" ); +int main(int, char**) { + test<int>(); + test<int>(3); + static_assert(constexpr_test<int>(), ""); + static_assert(constexpr_test<int>(3), ""); - { - const optional<const int> o(42); - optional<const int> o2(o); - assert(*o2 == 42); - } - { - using T = TestTypes::TestType; - T::reset(); - const optional<T> rhs; - assert(T::alive == 0); - const optional<T> lhs(rhs); - assert(lhs.has_value() == false); - assert(T::alive == 0); - } - TestTypes::TestType::reset(); - { - using T = TestTypes::TestType; - T::reset(); - const optional<T> rhs(42); - assert(T::alive == 1); - assert(T::value_constructed == 1); - assert(T::copy_constructed == 0); - const optional<T> lhs(rhs); - assert(lhs.has_value()); - assert(T::copy_constructed == 1); - assert(T::alive == 2); - } - TestTypes::TestType::reset(); - { - using namespace ConstexprTestTypes; - test<TestType>(); - test<TestType>(42); - } - { - using namespace TrivialTestTypes; - test<TestType>(); - test<TestType>(42); - } - { - test_throwing_ctor(); - } - { - test_reference_extension(); - } - { - constexpr std::optional<int> o1{4}; - constexpr std::optional<int> o2 = o1; - static_assert( *o2 == 4, "" ); - } + { + const optional<const int> o(42); + optional<const int> o2(o); + assert(*o2 == 42); + } + { + using T = TestTypes::TestType; + T::reset(); + const optional<T> rhs; + assert(T::alive == 0); + const optional<T> lhs(rhs); + assert(lhs.has_value() == false); + assert(T::alive == 0); + } + TestTypes::TestType::reset(); + { + using T = TestTypes::TestType; + T::reset(); + const optional<T> rhs(42); + assert(T::alive == 1); + assert(T::value_constructed == 1); + assert(T::copy_constructed == 0); + const optional<T> lhs(rhs); + assert(lhs.has_value()); + assert(T::copy_constructed == 1); + assert(T::alive == 2); + } + TestTypes::TestType::reset(); + { + using namespace ConstexprTestTypes; + test<TestType>(); + test<TestType>(42); + } + { + using namespace TrivialTestTypes; + test<TestType>(); + test<TestType>(42); + } + { + test_throwing_ctor(); + } + { + test_reference_extension(); + } + { + constexpr std::optional<int> o1{4}; + constexpr std::optional<int> o2 = o1; + static_assert(*o2 == 4, ""); + } - // LWG3836 https://wg21.link/LWG3836 - // std::optional<bool> conversion constructor optional(const optional<U>&) - // should take precedence over optional(U&&) with operator bool - { - std::optional<bool> o1(false); - std::optional<bool> o2(o1); - assert(!o2.value()); - } + // LWG3836 https://wg21.link/LWG3836 + // std::optional<bool> conversion constructor optional(const optional<U>&) + // should take precedence over optional(U&&) with operator bool + { + std::optional<bool> o1(false); + std::optional<bool> o2(o1); + assert(!o2.value()); + } return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ctor.verify.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ctor.verify.cpp index 775d2bd..00ca941 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ctor.verify.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ctor.verify.cpp @@ -13,35 +13,40 @@ // and shall satisfy the Cpp17Destructible requirements. // Note: array types do not satisfy the Cpp17Destructible requirements. -#include <optional> -#include <type_traits> #include <cassert> +#include <optional> #include "test_macros.h" -struct NonDestructible { ~NonDestructible() = delete; }; - -int main(int, char**) -{ - { - std::optional<char &> o1; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with a reference type is ill-formed}} +struct NonDestructible { + ~NonDestructible() = delete; +}; + +int main(int, char**) { + // clang-format off + { +#if TEST_STD_VER >= 26 + std::optional<int&&> opt2; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with an rvalue reference type is ill-formed}} +#else + std::optional<char&> o1; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with a reference type is ill-formed}} +#endif std::optional<NonDestructible> o2; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with a non-destructible type is ill-formed}} - std::optional<char[20]> o3; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with an array type is ill-formed}} - } + std::optional<char[20]> o3; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with an array type is ill-formed}} + } - { + { std::optional< std::in_place_t> o1; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}} std::optional<const std::in_place_t> o2; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}} std::optional< volatile std::in_place_t> o3; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}} std::optional<const volatile std::in_place_t> o4; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}} - } + } - { + { std::optional< std::nullopt_t> o1; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}} std::optional<const std::nullopt_t> o2; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}} std::optional< volatile std::nullopt_t> o3; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}} std::optional<const volatile std::nullopt_t> o4; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}} - } - - return 0; + } + // clang-format on + return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp index 9bfde5a..bc1d26a 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp @@ -12,67 +12,66 @@ // template<class T> // optional(T) -> optional<T>; -#include <optional> #include <cassert> +#include <optional> #include "test_macros.h" struct A {}; -int main(int, char**) -{ -// Test the explicit deduction guides - { -// optional(T) +int main(int, char**) { + // Test the explicit deduction guides + { + // optional(T) std::optional opt(5); ASSERT_SAME_TYPE(decltype(opt), std::optional<int>); assert(static_cast<bool>(opt)); assert(*opt == 5); - } + } - { -// optional(T) + { + // optional(T) std::optional opt(A{}); ASSERT_SAME_TYPE(decltype(opt), std::optional<A>); assert(static_cast<bool>(opt)); - } + } - { -// optional(const T&); + { + // optional(const T&); const int& source = 5; std::optional opt(source); ASSERT_SAME_TYPE(decltype(opt), std::optional<int>); assert(static_cast<bool>(opt)); assert(*opt == 5); - } + } - { -// optional(T*); + { + // optional(T*); const int* source = nullptr; std::optional opt(source); ASSERT_SAME_TYPE(decltype(opt), std::optional<const int*>); assert(static_cast<bool>(opt)); assert(*opt == nullptr); - } + } - { -// optional(T[]); + { + // optional(T[]); int source[] = {1, 2, 3}; std::optional opt(source); ASSERT_SAME_TYPE(decltype(opt), std::optional<int*>); assert(static_cast<bool>(opt)); assert((*opt)[0] == 1); - } + } -// Test the implicit deduction guides - { -// optional(optional); + // Test the implicit deduction guides + { + // optional(optional); std::optional<char> source('A'); std::optional opt(source); ASSERT_SAME_TYPE(decltype(opt), std::optional<char>); assert(static_cast<bool>(opt) == static_cast<bool>(source)); assert(*opt == *source); - } + } return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.verify.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.verify.cpp index 364f9b2..7ab842b 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.verify.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.verify.cpp @@ -13,25 +13,26 @@ // template<class T> // optional(T) -> optional<T>; -#include <optional> #include <cassert> +#include <optional> struct A {}; -int main(int, char**) -{ -// Test the explicit deduction guides +int main(int, char**) { + // Test the explicit deduction guides -// Test the implicit deduction guides - { -// optional() - std::optional opt; // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}optional'}} - } + // Test the implicit deduction guides - { -// optional(nullopt_t) - std::optional opt(std::nullopt); // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}} - } + // clang-format off + { + // optional() + std::optional opt; // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}optional'}} + } + { + // optional(nullopt_t) + std::optional opt(std::nullopt); // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}} + } + // clang-format on return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp index 61a365e..71d4d05 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp @@ -11,9 +11,9 @@ // constexpr optional() noexcept; +#include <cassert> #include <optional> #include <type_traits> -#include <cassert> #include "test_macros.h" #include "archetypes.h" @@ -21,61 +21,52 @@ using std::optional; template <class Opt> -void -test_constexpr() -{ - static_assert(std::is_nothrow_default_constructible<Opt>::value, ""); - static_assert(std::is_trivially_destructible<Opt>::value, ""); - static_assert(std::is_trivially_destructible<typename Opt::value_type>::value, ""); +void test_constexpr() { + static_assert(std::is_nothrow_default_constructible<Opt>::value, ""); + static_assert(std::is_trivially_destructible<Opt>::value, ""); + static_assert(std::is_trivially_destructible<typename Opt::value_type>::value, ""); - constexpr Opt opt; - static_assert(static_cast<bool>(opt) == false, ""); + constexpr Opt opt; + static_assert(static_cast<bool>(opt) == false, ""); - struct test_constexpr_ctor - : public Opt - { - constexpr test_constexpr_ctor() {} - }; + struct test_constexpr_ctor : public Opt { + constexpr test_constexpr_ctor() {} + }; } template <class Opt> -void -test() -{ - static_assert(std::is_nothrow_default_constructible<Opt>::value, ""); - static_assert(!std::is_trivially_destructible<Opt>::value, ""); - static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, ""); - { - Opt opt; - assert(static_cast<bool>(opt) == false); - } - { - const Opt opt; - assert(static_cast<bool>(opt) == false); - } +void test() { + static_assert(std::is_nothrow_default_constructible<Opt>::value, ""); + static_assert(!std::is_trivially_destructible<Opt>::value, ""); + static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, ""); + { + Opt opt; + assert(static_cast<bool>(opt) == false); + } + { + const Opt opt; + assert(static_cast<bool>(opt) == false); + } - struct test_constexpr_ctor - : public Opt - { - constexpr test_constexpr_ctor() {} - }; + struct test_constexpr_ctor : public Opt { + constexpr test_constexpr_ctor() {} + }; } -int main(int, char**) -{ - test_constexpr<optional<int>>(); - test_constexpr<optional<int*>>(); - test_constexpr<optional<ImplicitTypes::NoCtors>>(); - test_constexpr<optional<NonTrivialTypes::NoCtors>>(); - test_constexpr<optional<NonConstexprTypes::NoCtors>>(); - test<optional<NonLiteralTypes::NoCtors>>(); - // EXTENSIONS +int main(int, char**) { + test_constexpr<optional<int>>(); + test_constexpr<optional<int*>>(); + test_constexpr<optional<ImplicitTypes::NoCtors>>(); + test_constexpr<optional<NonTrivialTypes::NoCtors>>(); + test_constexpr<optional<NonConstexprTypes::NoCtors>>(); + test<optional<NonLiteralTypes::NoCtors>>(); + // EXTENSIONS #if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled. - test_constexpr<optional<int&>>(); - test_constexpr<optional<const int&>>(); - test_constexpr<optional<int&>>(); - test_constexpr<optional<NonLiteralTypes::NoCtors&>>(); - test_constexpr<optional<NonLiteralTypes::NoCtors&&>>(); + test_constexpr<optional<int&>>(); + test_constexpr<optional<const int&>>(); + test_constexpr<optional<int&>>(); + test_constexpr<optional<NonLiteralTypes::NoCtors&>>(); + test_constexpr<optional<NonLiteralTypes::NoCtors&&>>(); #endif return 0; diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/empty_in_place_t_does_not_clobber.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/empty_in_place_t_does_not_clobber.pass.cpp index 594aac7..f191748 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/empty_in_place_t_does_not_clobber.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/empty_in_place_t_does_not_clobber.pass.cpp @@ -15,9 +15,9 @@ // in_place_t constructor with no arguments when the Clang is trying to check // copy constructor. +#include <cassert> #include <optional> #include <type_traits> -#include <cassert> #include "test_macros.h" #include "archetypes.h" diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp index d8594bc..1b9882f 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp @@ -12,75 +12,70 @@ // template <class U> // explicit optional(const optional<U>& rhs); +#include <cassert> #include <optional> #include <type_traits> -#include <cassert> #include "test_macros.h" using std::optional; template <class T, class U> -TEST_CONSTEXPR_CXX20 void -test(const optional<U>& rhs, bool is_going_to_throw = false) -{ - static_assert(!(std::is_convertible<const optional<U>&, optional<T>>::value), ""); - bool rhs_engaged = static_cast<bool>(rhs); +TEST_CONSTEXPR_CXX20 void test(const optional<U>& rhs, bool is_going_to_throw = false) { + static_assert(!(std::is_convertible<const optional<U>&, optional<T>>::value), ""); + bool rhs_engaged = static_cast<bool>(rhs); #ifndef TEST_HAS_NO_EXCEPTIONS - try - { - optional<T> lhs(rhs); - assert(is_going_to_throw == false); - assert(static_cast<bool>(lhs) == rhs_engaged); - if (rhs_engaged) - assert(*lhs == T(*rhs)); - } - catch (int i) - { - assert(i == 6); - } -#else - if (is_going_to_throw) return; + try { optional<T> lhs(rhs); + assert(is_going_to_throw == false); assert(static_cast<bool>(lhs) == rhs_engaged); if (rhs_engaged) - assert(*lhs == T(*rhs)); + assert(*lhs == T(*rhs)); + } catch (int i) { + assert(i == 6); + } +#else + if (is_going_to_throw) + return; + optional<T> lhs(rhs); + assert(static_cast<bool>(lhs) == rhs_engaged); + if (rhs_engaged) + assert(*lhs == T(*rhs)); #endif } -class X -{ - int i_; +class X { + int i_; + public: - constexpr explicit X(int i) : i_(i) {} - constexpr X(const X& x) : i_(x.i_) {} - TEST_CONSTEXPR_CXX20 ~X() {i_ = 0;} - friend constexpr bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} + constexpr explicit X(int i) : i_(i) {} + constexpr X(const X& x) : i_(x.i_) {} + TEST_CONSTEXPR_CXX20 ~X() { i_ = 0; } + friend constexpr bool operator==(const X& x, const X& y) { return x.i_ == y.i_; } }; -class Y -{ - int i_; +class Y { + int i_; + public: - constexpr explicit Y(int i) : i_(i) {} + constexpr explicit Y(int i) : i_(i) {} - friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;} + friend constexpr bool operator==(const Y& x, const Y& y) { return x.i_ == y.i_; } }; int count = 0; -class Z -{ - int i_; +class Z { + int i_; + public: - explicit Z(int i) : i_(i) {TEST_THROW(6);} + explicit Z(int i) : i_(i) { TEST_THROW(6); } - friend bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;} + friend bool operator==(const Z& x, const Z& y) { return x.i_ == y.i_; } }; -template<class T, class U> -constexpr bool test_all() -{ +template <class T, class U> +constexpr bool test_all() { { optional<U> rhs; test<T>(rhs); @@ -92,27 +87,25 @@ constexpr bool test_all() return true; } - -int main(int, char**) -{ - test_all<X, int>(); - test_all<Y, int>(); +int main(int, char**) { + test_all<X, int>(); + test_all<Y, int>(); #if TEST_STD_VER > 17 - static_assert(test_all<X, int>()); - static_assert(test_all<Y, int>()); + static_assert(test_all<X, int>()); + static_assert(test_all<Y, int>()); #endif - { - typedef Z T; - typedef int U; - optional<U> rhs; - test<T>(rhs); - } - { - typedef Z T; - typedef int U; - optional<U> rhs(3); - test<T>(rhs, true); - } + { + typedef Z T; + typedef int U; + optional<U> rhs; + test<T>(rhs); + } + { + typedef Z T; + typedef int U; + optional<U> rhs(3); + test<T>(rhs, true); + } return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp index 708370a..bddbd4b 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp @@ -12,83 +12,77 @@ // template <class U> // explicit optional(optional<U>&& rhs); +#include <cassert> #include <optional> #include <type_traits> -#include <cassert> #include "test_macros.h" using std::optional; template <class T, class U> -TEST_CONSTEXPR_CXX20 void test(optional<U>&& rhs, bool is_going_to_throw = false) -{ - static_assert(!(std::is_convertible<optional<U>&&, optional<T>>::value), ""); - bool rhs_engaged = static_cast<bool>(rhs); +TEST_CONSTEXPR_CXX20 void test(optional<U>&& rhs, bool is_going_to_throw = false) { + static_assert(!(std::is_convertible<optional<U>&&, optional<T>>::value), ""); + bool rhs_engaged = static_cast<bool>(rhs); #ifndef TEST_HAS_NO_EXCEPTIONS - try - { - optional<T> lhs(std::move(rhs)); - assert(is_going_to_throw == false); - assert(static_cast<bool>(lhs) == rhs_engaged); - } - catch (int i) - { - assert(i == 6); - } -#else - if (is_going_to_throw) return; + try { optional<T> lhs(std::move(rhs)); + assert(is_going_to_throw == false); assert(static_cast<bool>(lhs) == rhs_engaged); + } catch (int i) { + assert(i == 6); + } +#else + if (is_going_to_throw) + return; + optional<T> lhs(std::move(rhs)); + assert(static_cast<bool>(lhs) == rhs_engaged); #endif } -class X -{ - int i_; +class X { + int i_; + public: - constexpr explicit X(int i) : i_(i) {} - constexpr X(X&& x) : i_(x.i_) { x.i_ = 0; } - TEST_CONSTEXPR_CXX20 ~X() {i_ = 0;} - friend constexpr bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} + constexpr explicit X(int i) : i_(i) {} + constexpr X(X&& x) : i_(x.i_) { x.i_ = 0; } + TEST_CONSTEXPR_CXX20 ~X() { i_ = 0; } + friend constexpr bool operator==(const X& x, const X& y) { return x.i_ == y.i_; } }; int count = 0; -class Z -{ +class Z { public: - explicit Z(int) { TEST_THROW(6); } + explicit Z(int) { TEST_THROW(6); } }; -TEST_CONSTEXPR_CXX20 bool test() -{ - { - optional<int> rhs; - test<X>(std::move(rhs)); - } - { - optional<int> rhs(3); - test<X>(std::move(rhs)); - } +TEST_CONSTEXPR_CXX20 bool test() { + { + optional<int> rhs; + test<X>(std::move(rhs)); + } + { + optional<int> rhs(3); + test<X>(std::move(rhs)); + } - return true; + return true; } -int main(int, char**) -{ +int main(int, char**) { #if TEST_STD_VER > 17 - static_assert(test()); + static_assert(test()); #endif - test(); - { - optional<int> rhs; - test<Z>(std::move(rhs)); - } - { - optional<int> rhs(3); - test<Z>(std::move(rhs), true); - } + test(); + { + optional<int> rhs; + test<Z>(std::move(rhs)); + } + { + optional<int> rhs(3); + test<Z>(std::move(rhs), true); + } return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp index 65276c5..9027544 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp @@ -13,136 +13,112 @@ // template <class... Args> // constexpr explicit optional(in_place_t, Args&&... args); +#include <cassert> #include <optional> #include <type_traits> -#include <cassert> #include "test_macros.h" -using std::optional; -using std::in_place_t; using std::in_place; +using std::in_place_t; +using std::optional; + +class X { + int i_; + int j_ = 0; -class X -{ - int i_; - int j_ = 0; public: - X() : i_(0) {} - X(int i) : i_(i) {} - X(int i, int j) : i_(i), j_(j) {} + X() : i_(0) {} + X(int i) : i_(i) {} + X(int i, int j) : i_(i), j_(j) {} - ~X() {} + ~X() {} - friend bool operator==(const X& x, const X& y) - {return x.i_ == y.i_ && x.j_ == y.j_;} + friend bool operator==(const X& x, const X& y) { return x.i_ == y.i_ && x.j_ == y.j_; } }; -class Y -{ - int i_; - int j_ = 0; +class Y { + int i_; + int j_ = 0; + public: - constexpr Y() : i_(0) {} - constexpr Y(int i) : i_(i) {} - constexpr Y(int i, int j) : i_(i), j_(j) {} + constexpr Y() : i_(0) {} + constexpr Y(int i) : i_(i) {} + constexpr Y(int i, int j) : i_(i), j_(j) {} - friend constexpr bool operator==(const Y& x, const Y& y) - {return x.i_ == y.i_ && x.j_ == y.j_;} + friend constexpr bool operator==(const Y& x, const Y& y) { return x.i_ == y.i_ && x.j_ == y.j_; } }; -class Z -{ +class Z { public: - Z(int) {TEST_THROW(6);} + Z(int) { TEST_THROW(6); } }; - -int main(int, char**) -{ - { - constexpr optional<int> opt(in_place, 5); - static_assert(static_cast<bool>(opt) == true, ""); - static_assert(*opt == 5, ""); - - struct test_constexpr_ctor - : public optional<int> - { - constexpr test_constexpr_ctor(in_place_t, int i) - : optional<int>(in_place, i) {} - }; - - } - { - optional<const int> opt(in_place, 5); - assert(*opt == 5); - } - { - const optional<X> opt(in_place); - assert(static_cast<bool>(opt) == true); - assert(*opt == X()); - } - { - const optional<X> opt(in_place, 5); - assert(static_cast<bool>(opt) == true); - assert(*opt == X(5)); - } - { - const optional<X> opt(in_place, 5, 4); - assert(static_cast<bool>(opt) == true); - assert(*opt == X(5, 4)); - } - { - constexpr optional<Y> opt(in_place); - static_assert(static_cast<bool>(opt) == true, ""); - static_assert(*opt == Y(), ""); - - struct test_constexpr_ctor - : public optional<Y> - { - constexpr test_constexpr_ctor(in_place_t) - : optional<Y>(in_place) {} - }; - - } - { - constexpr optional<Y> opt(in_place, 5); - static_assert(static_cast<bool>(opt) == true, ""); - static_assert(*opt == Y(5), ""); - - struct test_constexpr_ctor - : public optional<Y> - { - constexpr test_constexpr_ctor(in_place_t, int i) - : optional<Y>(in_place, i) {} - }; - - } - { - constexpr optional<Y> opt(in_place, 5, 4); - static_assert(static_cast<bool>(opt) == true, ""); - static_assert(*opt == Y(5, 4), ""); - - struct test_constexpr_ctor - : public optional<Y> - { - constexpr test_constexpr_ctor(in_place_t, int i, int j) - : optional<Y>(in_place, i, j) {} - }; - - } +int main(int, char**) { + { + constexpr optional<int> opt(in_place, 5); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == 5, ""); + + struct test_constexpr_ctor : public optional<int> { + constexpr test_constexpr_ctor(in_place_t, int i) : optional<int>(in_place, i) {} + }; + } + { + optional<const int> opt(in_place, 5); + assert(*opt == 5); + } + { + const optional<X> opt(in_place); + assert(static_cast<bool>(opt) == true); + assert(*opt == X()); + } + { + const optional<X> opt(in_place, 5); + assert(static_cast<bool>(opt) == true); + assert(*opt == X(5)); + } + { + const optional<X> opt(in_place, 5, 4); + assert(static_cast<bool>(opt) == true); + assert(*opt == X(5, 4)); + } + { + constexpr optional<Y> opt(in_place); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == Y(), ""); + + struct test_constexpr_ctor : public optional<Y> { + constexpr test_constexpr_ctor(in_place_t) : optional<Y>(in_place) {} + }; + } + { + constexpr optional<Y> opt(in_place, 5); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == Y(5), ""); + + struct test_constexpr_ctor : public optional<Y> { + constexpr test_constexpr_ctor(in_place_t, int i) : optional<Y>(in_place, i) {} + }; + } + { + constexpr optional<Y> opt(in_place, 5, 4); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == Y(5, 4), ""); + + struct test_constexpr_ctor : public optional<Y> { + constexpr test_constexpr_ctor(in_place_t, int i, int j) : optional<Y>(in_place, i, j) {} + }; + } #ifndef TEST_HAS_NO_EXCEPTIONS - { - try - { - const optional<Z> opt(in_place, 1); - assert(false); - } - catch (int i) - { - assert(i == 6); - } + { + try { + const optional<Z> opt(in_place, 1); + assert(false); + } catch (int i) { + assert(i == 6); } + } #endif return 0; diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp index 6c42df9..1993476 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp @@ -13,105 +13,93 @@ // constexpr // explicit optional(in_place_t, initializer_list<U> il, Args&&... args); +#include <cassert> +#include <memory> #include <optional> #include <type_traits> -#include <memory> #include <vector> -#include <cassert> #include "test_macros.h" -using std::optional; -using std::in_place_t; using std::in_place; +using std::in_place_t; +using std::optional; + +class X { + int i_; + int j_ = 0; -class X -{ - int i_; - int j_ = 0; public: - X() : i_(0) {} - X(int i) : i_(i) {} - X(int i, int j) : i_(i), j_(j) {} + X() : i_(0) {} + X(int i) : i_(i) {} + X(int i, int j) : i_(i), j_(j) {} - ~X() {} + ~X() {} - friend bool operator==(const X& x, const X& y) - {return x.i_ == y.i_ && x.j_ == y.j_;} + friend bool operator==(const X& x, const X& y) { return x.i_ == y.i_ && x.j_ == y.j_; } }; -class Y -{ - int i_; - int j_ = 0; +class Y { + int i_; + int j_ = 0; + public: - constexpr Y() : i_(0) {} - constexpr Y(int i) : i_(i) {} - constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {} + constexpr Y() : i_(0) {} + constexpr Y(int i) : i_(i) {} + constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {} - friend constexpr bool operator==(const Y& x, const Y& y) - {return x.i_ == y.i_ && x.j_ == y.j_;} + friend constexpr bool operator==(const Y& x, const Y& y) { return x.i_ == y.i_ && x.j_ == y.j_; } }; -class Z -{ - int i_; - int j_ = 0; +class Z { + int i_; + int j_ = 0; + public: - Z() : i_(0) {} - Z(int i) : i_(i) {} - Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) - {TEST_THROW(6);} + Z() : i_(0) {} + Z(int i) : i_(i) {} + Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) { TEST_THROW(6); } - friend bool operator==(const Z& x, const Z& y) - {return x.i_ == y.i_ && x.j_ == y.j_;} + friend bool operator==(const Z& x, const Z& y) { return x.i_ == y.i_ && x.j_ == y.j_; } }; -int main(int, char**) -{ - { - static_assert(!std::is_constructible<X, std::initializer_list<int>&>::value, ""); - static_assert(!std::is_constructible<optional<X>, std::initializer_list<int>&>::value, ""); - } - { - optional<std::vector<int>> opt(in_place, {3, 1}); - assert(static_cast<bool>(opt) == true); - assert((*opt == std::vector<int>{3, 1})); - assert(opt->size() == 2); - } - { - optional<std::vector<int>> opt(in_place, {3, 1}, std::allocator<int>()); - assert(static_cast<bool>(opt) == true); - assert((*opt == std::vector<int>{3, 1})); - assert(opt->size() == 2); - } - { - static_assert(std::is_constructible<optional<Y>, std::initializer_list<int>&>::value, ""); - constexpr optional<Y> opt(in_place, {3, 1}); - static_assert(static_cast<bool>(opt) == true, ""); - static_assert(*opt == Y{3, 1}, ""); - - struct test_constexpr_ctor - : public optional<Y> - { - constexpr test_constexpr_ctor(in_place_t, std::initializer_list<int> i) - : optional<Y>(in_place, i) {} - }; - - } +int main(int, char**) { + { + static_assert(!std::is_constructible<X, std::initializer_list<int>&>::value, ""); + static_assert(!std::is_constructible<optional<X>, std::initializer_list<int>&>::value, ""); + } + { + optional<std::vector<int>> opt(in_place, {3, 1}); + assert(static_cast<bool>(opt) == true); + assert((*opt == std::vector<int>{3, 1})); + assert(opt->size() == 2); + } + { + optional<std::vector<int>> opt(in_place, {3, 1}, std::allocator<int>()); + assert(static_cast<bool>(opt) == true); + assert((*opt == std::vector<int>{3, 1})); + assert(opt->size() == 2); + } + { + static_assert(std::is_constructible<optional<Y>, std::initializer_list<int>&>::value, ""); + constexpr optional<Y> opt(in_place, {3, 1}); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == Y{3, 1}, ""); + + struct test_constexpr_ctor : public optional<Y> { + constexpr test_constexpr_ctor(in_place_t, std::initializer_list<int> i) : optional<Y>(in_place, i) {} + }; + } #ifndef TEST_HAS_NO_EXCEPTIONS - { - static_assert(std::is_constructible<optional<Z>, std::initializer_list<int>&>::value, ""); - try - { - optional<Z> opt(in_place, {3, 1}); - assert(false); - } - catch (int i) - { - assert(i == 6); - } + { + static_assert(std::is_constructible<optional<Z>, std::initializer_list<int>&>::value, ""); + try { + optional<Z> opt(in_place, {3, 1}); + assert(false); + } catch (int i) { + assert(i == 6); } + } #endif return 0; diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp index f856c1d..583debc 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp @@ -12,211 +12,204 @@ // constexpr optional(optional<T>&& rhs); +#include <cassert> #include <optional> #include <type_traits> -#include <cassert> #include "test_macros.h" #include "archetypes.h" using std::optional; -template <class T, class ...InitArgs> -void test(InitArgs&&... args) -{ - const optional<T> orig(std::forward<InitArgs>(args)...); - optional<T> rhs(orig); - bool rhs_engaged = static_cast<bool>(rhs); - optional<T> lhs = std::move(rhs); - assert(static_cast<bool>(lhs) == rhs_engaged); - if (rhs_engaged) - assert(*lhs == *orig); +template <class T, class... InitArgs> +void test(InitArgs&&... args) { + const optional<T> orig(std::forward<InitArgs>(args)...); + optional<T> rhs(orig); + bool rhs_engaged = static_cast<bool>(rhs); + optional<T> lhs = std::move(rhs); + assert(static_cast<bool>(lhs) == rhs_engaged); + if (rhs_engaged) + assert(*lhs == *orig); } -template <class T, class ...InitArgs> -constexpr bool constexpr_test(InitArgs&&... args) -{ - static_assert( std::is_trivially_copy_constructible_v<T>, ""); // requirement - const optional<T> orig(std::forward<InitArgs>(args)...); - optional<T> rhs(orig); - optional<T> lhs = std::move(rhs); - return (lhs.has_value() == orig.has_value()) && - (lhs.has_value() ? *lhs == *orig : true); +template <class T, class... InitArgs> +constexpr bool constexpr_test(InitArgs&&... args) { + static_assert(std::is_trivially_copy_constructible_v<T>, ""); // requirement + const optional<T> orig(std::forward<InitArgs>(args)...); + optional<T> rhs(orig); + optional<T> lhs = std::move(rhs); + return (lhs.has_value() == orig.has_value()) && (lhs.has_value() ? *lhs == *orig : true); } void test_throwing_ctor() { #ifndef TEST_HAS_NO_EXCEPTIONS - struct Z { - Z() : count(0) {} - Z(Z&& o) : count(o.count + 1) - { if (count == 2) throw 6; } - int count; - }; - Z z; - optional<Z> rhs(std::move(z)); - try - { - optional<Z> lhs(std::move(rhs)); - assert(false); - } - catch (int i) - { - assert(i == 6); - } + struct Z { + Z() : count(0) {} + Z(Z&& o) : count(o.count + 1) { + if (count == 2) + throw 6; + } + int count; + }; + Z z; + optional<Z> rhs(std::move(z)); + try { + optional<Z> lhs(std::move(rhs)); + assert(false); + } catch (int i) { + assert(i == 6); + } #endif } +template <class T, class... InitArgs> +void test_ref(InitArgs&&... args) { + optional<T> rhs(std::forward<InitArgs>(args)...); + bool rhs_engaged = static_cast<bool>(rhs); + optional<T> lhs = std::move(rhs); + assert(static_cast<bool>(lhs) == rhs_engaged); + if (rhs_engaged) + assert(&(*lhs) == &(*rhs)); +} -template <class T, class ...InitArgs> -void test_ref(InitArgs&&... args) -{ - optional<T> rhs(std::forward<InitArgs>(args)...); - bool rhs_engaged = static_cast<bool>(rhs); - optional<T> lhs = std::move(rhs); - assert(static_cast<bool>(lhs) == rhs_engaged); - if (rhs_engaged) - assert(&(*lhs) == &(*rhs)); +void test_reference_extension() { +#if TEST_STD_VER >= 26 + using T = TestTypes::TestType; + T::reset(); + { + T t; + T::reset_constructors(); + test_ref<T&>(); + test_ref<T&>(t); + assert(T::alive == 1); + assert(T::constructed == 0); + assert(T::assigned == 0); + assert(T::destroyed == 0); + } + assert(T::destroyed == 1); + assert(T::alive == 0); + { + T t; + const T& ct = t; + T::reset_constructors(); + test_ref<T const&>(); + test_ref<T const&>(t); + test_ref<T const&>(ct); + assert(T::alive == 1); + assert(T::constructed == 0); + assert(T::assigned == 0); + assert(T::destroyed == 0); + } + assert(T::alive == 0); + assert(T::destroyed == 1); +# if 0 // FIXME: optional<T&&> is not allowed. + { + T t; + T::reset_constructors(); + test_ref<T&&>(); + test_ref<T&&>(std::move(t)); + assert(T::alive == 1); + assert(T::constructed == 0); + assert(T::assigned == 0); + assert(T::destroyed == 0); + } + assert(T::alive == 0); + assert(T::destroyed == 1); + { + T t; + const T& ct = t; + T::reset_constructors(); + test_ref<T const&&>(); + test_ref<T const&&>(std::move(t)); + test_ref<T const&&>(std::move(ct)); + assert(T::alive == 1); + assert(T::constructed == 0); + assert(T::assigned == 0); + assert(T::destroyed == 0); + } + assert(T::alive == 0); + assert(T::destroyed == 1); + { + static_assert(!std::is_copy_constructible_v<std::optional<T&&>>); + static_assert(!std::is_copy_constructible_v<std::optional<T const&&>>); + } +# endif +#endif } -void test_reference_extension() -{ -#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled. +int main(int, char**) { + test<int>(); + test<int>(3); + static_assert(constexpr_test<int>(), ""); + static_assert(constexpr_test<int>(3), ""); + + { + optional<const int> o(42); + optional<const int> o2(std::move(o)); + assert(*o2 == 42); + } + { using T = TestTypes::TestType; T::reset(); - { - T t; - T::reset_constructors(); - test_ref<T&>(); - test_ref<T&>(t); - assert(T::alive == 1); - assert(T::constructed == 0); - assert(T::assigned == 0); - assert(T::destroyed == 0); - } - assert(T::destroyed == 1); + optional<T> rhs; assert(T::alive == 0); - { - T t; - const T& ct = t; - T::reset_constructors(); - test_ref<T const&>(); - test_ref<T const&>(t); - test_ref<T const&>(ct); - assert(T::alive == 1); - assert(T::constructed == 0); - assert(T::assigned == 0); - assert(T::destroyed == 0); - } - assert(T::alive == 0); - assert(T::destroyed == 1); - { - T t; - T::reset_constructors(); - test_ref<T&&>(); - test_ref<T&&>(std::move(t)); - assert(T::alive == 1); - assert(T::constructed == 0); - assert(T::assigned == 0); - assert(T::destroyed == 0); - } - assert(T::alive == 0); - assert(T::destroyed == 1); - { - T t; - const T& ct = t; - T::reset_constructors(); - test_ref<T const&&>(); - test_ref<T const&&>(std::move(t)); - test_ref<T const&&>(std::move(ct)); - assert(T::alive == 1); - assert(T::constructed == 0); - assert(T::assigned == 0); - assert(T::destroyed == 0); - } + const optional<T> lhs(std::move(rhs)); + assert(lhs.has_value() == false); + assert(rhs.has_value() == false); assert(T::alive == 0); - assert(T::destroyed == 1); - { - static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, ""); - static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, ""); - } -#endif -} - - -int main(int, char**) -{ - test<int>(); - test<int>(3); - static_assert(constexpr_test<int>(), "" ); - static_assert(constexpr_test<int>(3), "" ); - - { - optional<const int> o(42); - optional<const int> o2(std::move(o)); - assert(*o2 == 42); - } - { - using T = TestTypes::TestType; - T::reset(); - optional<T> rhs; - assert(T::alive == 0); - const optional<T> lhs(std::move(rhs)); - assert(lhs.has_value() == false); - assert(rhs.has_value() == false); - assert(T::alive == 0); - } - TestTypes::TestType::reset(); - { - using T = TestTypes::TestType; - T::reset(); - optional<T> rhs(42); - assert(T::alive == 1); - assert(T::value_constructed == 1); - assert(T::move_constructed == 0); - const optional<T> lhs(std::move(rhs)); - assert(lhs.has_value()); - assert(rhs.has_value()); - assert(lhs.value().value == 42); - assert(rhs.value().value == -1); - assert(T::move_constructed == 1); - assert(T::alive == 2); - } - TestTypes::TestType::reset(); - { - using namespace ConstexprTestTypes; - test<TestType>(); - test<TestType>(42); - } - { - using namespace TrivialTestTypes; - test<TestType>(); - test<TestType>(42); - } - { - test_throwing_ctor(); - } - { - struct ThrowsMove { - ThrowsMove() noexcept(false) {} - ThrowsMove(ThrowsMove const&) noexcept(false) {} - ThrowsMove(ThrowsMove &&) noexcept(false) {} - }; - static_assert(!std::is_nothrow_move_constructible<optional<ThrowsMove>>::value, ""); - struct NoThrowMove { - NoThrowMove() noexcept(false) {} - NoThrowMove(NoThrowMove const&) noexcept(false) {} - NoThrowMove(NoThrowMove &&) noexcept(true) {} - }; - static_assert(std::is_nothrow_move_constructible<optional<NoThrowMove>>::value, ""); - } - { - test_reference_extension(); - } - { + } + TestTypes::TestType::reset(); + { + using T = TestTypes::TestType; + T::reset(); + optional<T> rhs(42); + assert(T::alive == 1); + assert(T::value_constructed == 1); + assert(T::move_constructed == 0); + const optional<T> lhs(std::move(rhs)); + assert(lhs.has_value()); + assert(rhs.has_value()); + assert(lhs.value().value == 42); + assert(rhs.value().value == -1); + assert(T::move_constructed == 1); + assert(T::alive == 2); + } + TestTypes::TestType::reset(); + { + using namespace ConstexprTestTypes; + test<TestType>(); + test<TestType>(42); + } + { + using namespace TrivialTestTypes; + test<TestType>(); + test<TestType>(42); + } + { + test_throwing_ctor(); + } + { + struct ThrowsMove { + ThrowsMove() noexcept(false) {} + ThrowsMove(ThrowsMove const&) noexcept(false) {} + ThrowsMove(ThrowsMove&&) noexcept(false) {} + }; + static_assert(!std::is_nothrow_move_constructible<optional<ThrowsMove>>::value, ""); + struct NoThrowMove { + NoThrowMove() noexcept(false) {} + NoThrowMove(NoThrowMove const&) noexcept(false) {} + NoThrowMove(NoThrowMove&&) noexcept(true) {} + }; + static_assert(std::is_nothrow_move_constructible<optional<NoThrowMove>>::value, ""); + } + { + test_reference_extension(); + } + { constexpr std::optional<int> o1{4}; constexpr std::optional<int> o2 = std::move(o1); - static_assert( *o2 == 4, "" ); - } + static_assert(*o2 == 4, ""); + } return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp index 36a60f2..c1bdd81 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp @@ -11,66 +11,57 @@ // constexpr optional(nullopt_t) noexcept; +#include <cassert> #include <optional> #include <type_traits> -#include <cassert> #include "archetypes.h" #include "test_macros.h" -using std::optional; -using std::nullopt_t; using std::nullopt; +using std::nullopt_t; +using std::optional; template <class Opt> -void -test_constexpr() -{ - static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, ""); - static_assert(std::is_trivially_destructible<Opt>::value, ""); - static_assert(std::is_trivially_destructible<typename Opt::value_type>::value, ""); +void test_constexpr() { + static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, ""); + static_assert(std::is_trivially_destructible<Opt>::value, ""); + static_assert(std::is_trivially_destructible<typename Opt::value_type>::value, ""); - constexpr Opt opt(nullopt); - static_assert(static_cast<bool>(opt) == false, ""); + constexpr Opt opt(nullopt); + static_assert(static_cast<bool>(opt) == false, ""); - struct test_constexpr_ctor - : public Opt - { - constexpr test_constexpr_ctor() {} - }; + struct test_constexpr_ctor : public Opt { + constexpr test_constexpr_ctor() {} + }; } template <class Opt> -void -test() -{ - static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, ""); - static_assert(!std::is_trivially_destructible<Opt>::value, ""); - static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, ""); - { +void test() { + static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, ""); + static_assert(!std::is_trivially_destructible<Opt>::value, ""); + static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, ""); + { Opt opt(nullopt); assert(static_cast<bool>(opt) == false); - } - { + } + { const Opt opt(nullopt); assert(static_cast<bool>(opt) == false); - } - struct test_constexpr_ctor - : public Opt - { - constexpr test_constexpr_ctor() {} - }; + } + struct test_constexpr_ctor : public Opt { + constexpr test_constexpr_ctor() {} + }; } -int main(int, char**) -{ - test_constexpr<optional<int>>(); - test_constexpr<optional<int*>>(); - test_constexpr<optional<ImplicitTypes::NoCtors>>(); - test_constexpr<optional<NonTrivialTypes::NoCtors>>(); - test_constexpr<optional<NonConstexprTypes::NoCtors>>(); - test<optional<NonLiteralTypes::NoCtors>>(); +int main(int, char**) { + test_constexpr<optional<int>>(); + test_constexpr<optional<int*>>(); + test_constexpr<optional<ImplicitTypes::NoCtors>>(); + test_constexpr<optional<NonTrivialTypes::NoCtors>>(); + test_constexpr<optional<NonConstexprTypes::NoCtors>>(); + test<optional<NonLiteralTypes::NoCtors>>(); return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp index 14c400c..709b106 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp @@ -23,75 +23,68 @@ using std::optional; template <class T, class U> -TEST_CONSTEXPR_CXX20 void -test(optional<U>&& rhs, bool is_going_to_throw = false) -{ - bool rhs_engaged = static_cast<bool>(rhs); +TEST_CONSTEXPR_CXX20 void test(optional<U>&& rhs, bool is_going_to_throw = false) { + bool rhs_engaged = static_cast<bool>(rhs); #ifndef TEST_HAS_NO_EXCEPTIONS - try - { - optional<T> lhs = std::move(rhs); - assert(is_going_to_throw == false); - assert(static_cast<bool>(lhs) == rhs_engaged); - } - catch (int i) - { - assert(i == 6); - } -#else - if (is_going_to_throw) return; + try { optional<T> lhs = std::move(rhs); + assert(is_going_to_throw == false); assert(static_cast<bool>(lhs) == rhs_engaged); + } catch (int i) { + assert(i == 6); + } +#else + if (is_going_to_throw) + return; + optional<T> lhs = std::move(rhs); + assert(static_cast<bool>(lhs) == rhs_engaged); #endif } -class X -{ - int i_; +class X { + int i_; + public: - TEST_CONSTEXPR_CXX20 X(int i) : i_(i) {} - TEST_CONSTEXPR_CXX20 X(X&& x) : i_(std::exchange(x.i_, 0)) {} - TEST_CONSTEXPR_CXX20 ~X() {i_ = 0;} - friend constexpr bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} + TEST_CONSTEXPR_CXX20 X(int i) : i_(i) {} + TEST_CONSTEXPR_CXX20 X(X&& x) : i_(std::exchange(x.i_, 0)) {} + TEST_CONSTEXPR_CXX20 ~X() { i_ = 0; } + friend constexpr bool operator==(const X& x, const X& y) { return x.i_ == y.i_; } }; -struct Z -{ - Z(int) { TEST_THROW(6); } +struct Z { + Z(int) { TEST_THROW(6); } }; -template<class T, class U> -TEST_CONSTEXPR_CXX20 bool test_all() -{ - { - optional<T> rhs; - test<U>(std::move(rhs)); - } - { - optional<T> rhs(short{3}); - test<U>(std::move(rhs)); - } - return true; +template <class T, class U> +TEST_CONSTEXPR_CXX20 bool test_all() { + { + optional<T> rhs; + test<U>(std::move(rhs)); + } + { + optional<T> rhs(short{3}); + test<U>(std::move(rhs)); + } + return true; } -int main(int, char**) -{ - test_all<short, int>(); - test_all<int, X>(); +int main(int, char**) { + test_all<short, int>(); + test_all<int, X>(); #if TEST_STD_VER > 17 - static_assert(test_all<short, int>()); - static_assert(test_all<int, X>()); + static_assert(test_all<short, int>()); + static_assert(test_all<int, X>()); #endif - { - optional<int> rhs; - test<Z>(std::move(rhs)); - } - { - optional<int> rhs(3); - test<Z>(std::move(rhs), true); - } + { + optional<int> rhs; + test<Z>(std::move(rhs)); + } + { + optional<int> rhs(3); + test<Z>(std::move(rhs), true); + } - static_assert(!(std::is_constructible<optional<X>, optional<Z>>::value), ""); + static_assert(!(std::is_constructible<optional<X>, optional<Z>>::value), ""); return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ref_constructs_from_temporary.verify.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ref_constructs_from_temporary.verify.cpp new file mode 100644 index 0000000..01b241f --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ref_constructs_from_temporary.verify.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++26 + +// optional + +#include <optional> +#include <utility> + +struct X { + int i; + + X(int j) : i(j) {} +}; + +int main(int, char**) { + const std::optional<int> _co(1); + std::optional<int> _o(1); + + // expected-error-re@*:* 8 {{call to deleted constructor of 'std::optional<{{.*}}>'}} + std::optional<const int&> o1{1}; // optional(U&&) + std::optional<const int&> o2{std::optional<int>(1)}; // optional(optional<U>&&) + std::optional<const int&> o3{_co}; // optional(const optional<U>&) + std::optional<const int&> o4{_o}; // optional(optional<U>&) + std::optional<const X&> o5{1}; // optional(U&&) + std::optional<const X&> o6{std::optional<int>(1)}; // optional(optional<U>&&) + std::optional<const X&> o7{_co}; // optional(const optional<U>&) + std::optional<const X&> o8{_o}; // optional(optional<U>&) +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ref_t.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ref_t.pass.cpp new file mode 100644 index 0000000..5755274 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ref_t.pass.cpp @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++26 + +// <optional> + +#include <cassert> +#include <optional> +#include <type_traits> +#include <utility> + +template <typename RefType, std::remove_reference_t<RefType> _Val> +constexpr bool test() { + std::remove_reference_t<RefType> item{_Val}; + std::optional<RefType> opt{item}; + + { + assert(*opt == item); + assert(&(*opt) == &item); + } + { + assert(*std::as_const(opt) == item); + assert(&(*std::as_const(opt)) == &item); + } + + return true; +} + +template <typename T> +constexpr T foo(T val) { + return val; +} + +template <typename T, T _Val> +constexpr bool fn_ref_test() { + std::optional<T (&)(T)> opt{foo<T>}; + assert(opt.has_value()); + assert((*opt)(_Val) == _Val); + + return true; +} + +template <typename T, T _Val> +constexpr bool array_ref_test() { + T arr[5]{}; + std::optional<T(&)[5]> opt{arr}; + + assert(opt.has_value()); + (*opt)[0] = _Val; + assert((*opt)[0] == _Val); + assert(arr[0] == _Val); + + return true; +} + +constexpr bool tests() { + assert((test<int&, 1>())); + assert((test<double&, 1.0>())); + assert((fn_ref_test<int, 1>())); + assert((array_ref_test<int, 1>())); + assert((fn_ref_test<double, 1.0>())); + assert((array_ref_test<double, 1.0>())); + return true; +} + +int main(int, char**) { + static_assert(tests()); + tests(); +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp index 1242595..e73eef4 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp @@ -12,137 +12,118 @@ // constexpr optional(T&& v); +#include <cassert> #include <optional> #include <type_traits> -#include <cassert> #include "test_macros.h" #include "archetypes.h" - using std::optional; - -class Z -{ +class Z { public: - Z(int) {} - Z(Z&&) {TEST_THROW(6);} + Z(int) {} + Z(Z&&) { TEST_THROW(6); } }; - -int main(int, char**) -{ - { - typedef int T; - constexpr optional<T> opt(T(5)); - static_assert(static_cast<bool>(opt) == true, ""); - static_assert(*opt == 5, ""); - - struct test_constexpr_ctor - : public optional<T> - { - constexpr test_constexpr_ctor(T&&) {} - }; - } - { - typedef double T; - constexpr optional<T> opt(T(3)); - static_assert(static_cast<bool>(opt) == true, ""); - static_assert(*opt == 3, ""); - - struct test_constexpr_ctor - : public optional<T> - { - constexpr test_constexpr_ctor(T&&) {} - }; - } - { - const int x = 42; - optional<const int> o(std::move(x)); - assert(*o == 42); - } - { - typedef TestTypes::TestType T; - T::reset(); - optional<T> opt = T{3}; - assert(T::alive == 1); - assert(T::move_constructed == 1); - assert(static_cast<bool>(opt) == true); - assert(opt.value().value == 3); - } - { - typedef ExplicitTestTypes::TestType T; - static_assert(!std::is_convertible<T&&, optional<T>>::value, ""); - T::reset(); - optional<T> opt(T{3}); - assert(T::alive == 1); - assert(T::move_constructed == 1); - assert(static_cast<bool>(opt) == true); - assert(opt.value().value == 3); - } - { - typedef TestTypes::TestType T; - T::reset(); - optional<T> opt = {3}; - assert(T::alive == 1); - assert(T::value_constructed == 1); - assert(T::copy_constructed == 0); - assert(T::move_constructed == 0); - assert(static_cast<bool>(opt) == true); - assert(opt.value().value == 3); - } - { - typedef ConstexprTestTypes::TestType T; - constexpr optional<T> opt = {T(3)}; - static_assert(static_cast<bool>(opt) == true, ""); - static_assert(opt.value().value == 3, ""); - - struct test_constexpr_ctor - : public optional<T> - { - constexpr test_constexpr_ctor(const T&) {} - }; - } - { - typedef ConstexprTestTypes::TestType T; - constexpr optional<T> opt = {3}; - static_assert(static_cast<bool>(opt) == true, ""); - static_assert(opt.value().value == 3, ""); - - struct test_constexpr_ctor - : public optional<T> - { - constexpr test_constexpr_ctor(const T&) {} - }; - } - { - typedef ExplicitConstexprTestTypes::TestType T; - static_assert(!std::is_convertible<T&&, optional<T>>::value, ""); - constexpr optional<T> opt(T{3}); - static_assert(static_cast<bool>(opt) == true, ""); - static_assert(opt.value().value == 3, ""); - - struct test_constexpr_ctor - : public optional<T> - { - constexpr test_constexpr_ctor(T&&) {} - }; - - } +int main(int, char**) { + { + typedef int T; + constexpr optional<T> opt(T(5)); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == 5, ""); + + struct test_constexpr_ctor : public optional<T> { + constexpr test_constexpr_ctor(T&&) {} + }; + } + { + typedef double T; + constexpr optional<T> opt(T(3)); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == 3, ""); + + struct test_constexpr_ctor : public optional<T> { + constexpr test_constexpr_ctor(T&&) {} + }; + } + { + const int x = 42; + optional<const int> o(std::move(x)); + assert(*o == 42); + } + { + typedef TestTypes::TestType T; + T::reset(); + optional<T> opt = T{3}; + assert(T::alive == 1); + assert(T::move_constructed == 1); + assert(static_cast<bool>(opt) == true); + assert(opt.value().value == 3); + } + { + typedef ExplicitTestTypes::TestType T; + static_assert(!std::is_convertible<T&&, optional<T>>::value, ""); + T::reset(); + optional<T> opt(T{3}); + assert(T::alive == 1); + assert(T::move_constructed == 1); + assert(static_cast<bool>(opt) == true); + assert(opt.value().value == 3); + } + { + typedef TestTypes::TestType T; + T::reset(); + optional<T> opt = {3}; + assert(T::alive == 1); + assert(T::value_constructed == 1); + assert(T::copy_constructed == 0); + assert(T::move_constructed == 0); + assert(static_cast<bool>(opt) == true); + assert(opt.value().value == 3); + } + { + typedef ConstexprTestTypes::TestType T; + constexpr optional<T> opt = {T(3)}; + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(opt.value().value == 3, ""); + + struct test_constexpr_ctor : public optional<T> { + constexpr test_constexpr_ctor(const T&) {} + }; + } + { + typedef ConstexprTestTypes::TestType T; + constexpr optional<T> opt = {3}; + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(opt.value().value == 3, ""); + + struct test_constexpr_ctor : public optional<T> { + constexpr test_constexpr_ctor(const T&) {} + }; + } + { + typedef ExplicitConstexprTestTypes::TestType T; + static_assert(!std::is_convertible<T&&, optional<T>>::value, ""); + constexpr optional<T> opt(T{3}); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(opt.value().value == 3, ""); + + struct test_constexpr_ctor : public optional<T> { + constexpr test_constexpr_ctor(T&&) {} + }; + } #ifndef TEST_HAS_NO_EXCEPTIONS - { - try - { - Z z(3); - optional<Z> opt(std::move(z)); - assert(false); - } - catch (int i) - { - assert(i == 6); - } + { + try { + Z z(3); + optional<Z> opt(std::move(z)); + assert(false); + } catch (int i) { + assert(i == 6); } + } #endif return 0; diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp index c004427..1202879 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp @@ -11,9 +11,9 @@ // ~optional(); +#include <cassert> #include <optional> #include <type_traits> -#include <cassert> #include "test_macros.h" @@ -64,6 +64,24 @@ int main(int, char**) } assert(X::dtor_called == true); } +#if TEST_STD_VER >= 26 + { + typedef X& T; + static_assert(std::is_trivially_destructible_v<T>); + static_assert(std::is_trivially_destructible_v<optional<T>>); + } + X::dtor_called = false; + X x; + { + optional<X&> opt{x}; + assert(X::dtor_called == false); + } + assert(X::dtor_called == false); - return 0; + { + static_assert(std::is_trivially_destructible_v<X (&)()>); + static_assert(std::is_trivially_destructible_v<optional<X (&)()>>); + } +#endif + return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp index 7029b37..e23e481 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp @@ -69,5 +69,16 @@ int main(int, char**) X::dtor_called = false; } - return 0; +#if TEST_STD_VER >= 26 + { + X x{}; + optional<X&> opt(x); + X::dtor_called = false; + opt.reset(); + assert(X::dtor_called == false); + assert(static_cast<bool>(opt) == false); + } +#endif + + return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp index 49b4d21..6c1bf8a 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp @@ -50,7 +50,19 @@ int main(int, char**) optional<X> opt(X{}); assert((*opt).test() == 4); } +#if TEST_STD_VER >= 26 + { + X x{}; + optional<X&> opt(x); + ASSERT_SAME_TYPE(decltype(*opt), X&); + ASSERT_NOEXCEPT(*opt); + } + { + X x{}; + optional<X&> opt(x); + assert((*opt).test() == 4); + } +#endif static_assert(test() == 7, ""); - return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp index ff86d95..c15d4e4 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp @@ -43,6 +43,25 @@ int main(int, char**) constexpr optional<X> opt(X{}); static_assert((*opt).test() == 3, ""); } +#if TEST_STD_VER >= 26 + { + X x{}; + const optional<X&> opt{x}; + ASSERT_SAME_TYPE(decltype(*opt), X&); + ASSERT_NOEXCEPT(*opt); + } + { + X x{}; + const optional<const X&> opt{x}; + ASSERT_SAME_TYPE(decltype(*opt), const X&); + ASSERT_NOEXCEPT(*opt); + } + { + static constexpr X x{}; + constexpr optional<const X&> opt(x); + static_assert((*opt).test() == 3); + } +#endif { constexpr optional<Y> opt(Y{}); assert((*opt).test() == 2); diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp index 6998e02..9873a76 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp @@ -33,6 +33,13 @@ int main(int, char**) constexpr optional<int> opt(0); static_assert(opt.has_value(), ""); } +#if TEST_STD_VER >= 26 + { + static constexpr int i = 0; + constexpr optional<const int&> opt{i}; + static_assert(opt.has_value()); + } +#endif - return 0; + return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp index 2b5fba5..96d2274 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp @@ -19,9 +19,9 @@ using std::optional; -struct X -{ - int test() noexcept {return 3;} +struct X { + int test() noexcept { return 3; } + int test() const noexcept { return 3; } }; struct Y @@ -47,6 +47,30 @@ int main(int, char**) optional<X> opt(X{}); assert(opt->test() == 3); } +#if TEST_STD_VER >= 26 + { + X x{}; + std::optional<X&> opt(x); + ASSERT_SAME_TYPE(decltype(opt.operator->()), X*); + ASSERT_NOEXCEPT(opt.operator->()); + } + { + X x{}; + std::optional<const X&> opt(x); + ASSERT_SAME_TYPE(decltype(opt.operator->()), const X*); + ASSERT_NOEXCEPT(opt.operator->()); + } + { + X x{}; + optional<X&> opt{x}; + assert(opt->test() == 3); + } + { + X x{}; + optional<const X&> opt{x}; + assert(opt->test() == 3); + } +#endif { static_assert(test() == 3, ""); } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp index d8ce932..e9694fd6 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp @@ -54,6 +54,25 @@ int main(int, char**) constexpr optional<Z> opt(Z{}); static_assert(opt->test() == 1, ""); } +#if TEST_STD_VER >= 26 + { + X x{}; + const std::optional<X&> opt(x); + ASSERT_SAME_TYPE(decltype(opt.operator->()), X*); + ASSERT_NOEXCEPT(opt.operator->()); + } + { + X x{}; + const std::optional<const X&> opt(x); + ASSERT_SAME_TYPE(decltype(opt.operator->()), const X*); + ASSERT_NOEXCEPT(opt.operator->()); + } + { + static constexpr Z z{}; + constexpr optional<const Z&> opt(z); + static_assert(opt->test() == 1); + } +#endif return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp index 781784c6..22b74f5 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp @@ -56,6 +56,14 @@ int main(int, char**) opt.emplace(); assert(opt.value().test() == 4); } +#if TEST_STD_VER >= 26 + { + X x; + optional<X&> opt{x}; + ASSERT_NOT_NOEXCEPT(opt.value()); + ASSERT_SAME_TYPE(decltype(opt.value()), X&); + } +#endif #ifndef TEST_HAS_NO_EXCEPTIONS { optional<X> opt; diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp index 8c063ae..66890ff 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp @@ -80,6 +80,14 @@ constexpr int test() assert((std::move(opt).value_or({2, 3}) == Z{2, 3})); assert(!opt); } +#if TEST_STD_VER >= 26 + { + int y = 2; + optional<int&> opt; + assert(std::move(opt).value_or(y) == 2); + assert(!opt); + } +#endif return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp index ec42890..6bd308b 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp @@ -79,6 +79,12 @@ int main(int, char**) const optional<X> opt; assert(opt.value_or({Y(3)}) == 4); } - - return 0; +#if TEST_STD_VER >= 26 + { + X y{3}; + const optional<X&> opt; + assert(opt.value_or(y) == 3); + } +#endif + return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp index e3a2fdb..a82ca61 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp @@ -13,9 +13,10 @@ // noexcept(is_nothrow_move_constructible<T>::value && // is_nothrow_swappable<T>::value) +#include <cassert> +#include <memory> #include <optional> #include <type_traits> -#include <cassert> #include "test_macros.h" #include "archetypes.h" @@ -127,6 +128,74 @@ TEST_CONSTEXPR_CXX20 bool check_swap() return true; } +#if TEST_STD_VER >= 26 +template <typename T> +constexpr bool check_swap_ref() { + { + optional<T&> opt1; + optional<T&> opt2; + static_assert(noexcept(opt1.swap(opt2)) == true); + assert(static_cast<bool>(opt1) == false); + assert(static_cast<bool>(opt2) == false); + opt1.swap(opt2); + assert(static_cast<bool>(opt1) == false); + assert(static_cast<bool>(opt2) == false); + } + + { + T one{1}; + optional<T&> opt1(one); + optional<T&> opt2; + static_assert(noexcept(opt1.swap(opt2)) == true); + assert(static_cast<bool>(opt1) == true); + assert(std::addressof(*opt1) == std::addressof(one)); + assert(static_cast<bool>(opt2) == false); + opt1.swap(opt2); + assert(static_cast<bool>(opt1) == false); + assert(static_cast<bool>(opt2) == true); + assert(std::addressof(*opt2) == std::addressof(one)); + } + + { + T two{2}; + optional<T&> opt1; + optional<T&> opt2(two); + static_assert(noexcept(opt1.swap(opt2)) == true); + assert(static_cast<bool>(opt1) == false); + assert(static_cast<bool>(opt2) == true); + assert(std::addressof(*opt2) == std::addressof(two)); + opt1.swap(opt2); + assert(static_cast<bool>(opt1) == true); + assert(std::addressof(*opt1) == std::addressof(two)); + assert(static_cast<bool>(opt2) == false); + } + + { + T one{1}; + T two{2}; + + optional<T&> opt1(one); + optional<T&> opt2(two); + static_assert(noexcept(opt1.swap(opt2)) == true); + assert(static_cast<bool>(opt1) == true); + assert(*opt1 == 1); + assert(std::addressof(*opt1) == std::addressof(one)); + assert(static_cast<bool>(opt2) == true); + assert(*opt2 == 2); + assert(std::addressof(*opt2) == std::addressof(two)); + opt1.swap(opt2); + assert(static_cast<bool>(opt1) == true); + assert(*opt1 == 2); + assert(std::addressof(*opt1) == std::addressof(two)); + assert(static_cast<bool>(opt2) == true); + assert(*opt2 == 1); + assert(std::addressof(*opt2) == std::addressof(one)); + } + + return true; +} +#endif + int main(int, char**) { check_swap<int>(); @@ -135,6 +204,12 @@ int main(int, char**) static_assert(check_swap<int>()); static_assert(check_swap<W>()); #endif +#if TEST_STD_VER >= 26 + static_assert(check_swap_ref<int>()); + static_assert(check_swap_ref<W>()); + check_swap_ref<int>(); + check_swap_ref<W>(); +#endif { optional<X> opt1; optional<X> opt2; diff --git a/libcxx/test/std/utilities/optional/optional.object/optional_requires_destructible_object.verify.cpp b/libcxx/test/std/utilities/optional/optional.object/optional_requires_destructible_object.verify.cpp index a96c3c6..a956ab3 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional_requires_destructible_object.verify.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional_requires_destructible_object.verify.cpp @@ -13,6 +13,8 @@ #include <optional> +#include "test_macros.h" + using std::optional; struct X @@ -25,9 +27,13 @@ int main(int, char**) { using std::optional; { - // expected-error-re@optional:* 2 {{static assertion failed{{.*}}instantiation of optional with a reference type is ill-formed}} - optional<int&> opt1; - optional<int&&> opt2; +#if TEST_STD_VER >= 26 + // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with an rvalue reference type is ill-formed}} +#else + // expected-error-re@optional:* 2 {{static assertion failed{{.*}}instantiation of optional with a reference type is ill-formed}} +#endif + optional<int&> opt1; + optional<int&&> opt2; } { // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with a non-destructible type is ill-formed}} diff --git a/libcxx/test/std/utilities/optional/optional.object/types.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/types.pass.cpp index d097559..ecbc6b4 100644 --- a/libcxx/test/std/utilities/optional/optional.object/types.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/types.pass.cpp @@ -36,6 +36,11 @@ int main(int, char**) test<optional<const int>, const int>(); test<optional<double>, double>(); test<optional<const double>, const double>(); - - return 0; +#if TEST_STD_VER >= 26 + test<optional<int&>, int>(); + test<optional<const int&>, const int>(); + test<optional<double&>, double>(); + test<optional<const double&>, const double>(); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp b/libcxx/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp index e325a7a..c276451 100644 --- a/libcxx/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp @@ -13,10 +13,10 @@ // template <class T> // constexpr optional<decay_t<T>> make_optional(T&& v); +#include <cassert> +#include <memory> #include <optional> #include <string> -#include <memory> -#include <cassert> #include "test_macros.h" diff --git a/libcxx/test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp b/libcxx/test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp index 23f131d..5dd1d6f 100644 --- a/libcxx/test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp @@ -15,13 +15,30 @@ // GCC crashes on this file, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120577 // XFAIL: gcc-15 +#include <cassert> +#include <memory> #include <optional> #include <string> -#include <memory> -#include <cassert> +#include <string_view> #include "test_macros.h" +template <typename T> +constexpr bool test_ref() { + T i{0}; + auto opt = std::make_optional<T&>(i); + +#if TEST_STD_VER < 26 + assert((std::is_same_v<decltype(opt), std::optional<T>>)); +#else + assert((std::is_same_v<decltype(opt), std::optional<T&>>)); +#endif + + assert(*opt == 0); + + return true; +} + int main(int, char**) { { @@ -43,6 +60,12 @@ int main(int, char**) auto opt = std::make_optional<std::string>(4u, 'X'); assert(*opt == "XXXX"); } + using namespace std::string_view_literals; + + static_assert(test_ref<int>()); + assert((test_ref<int>())); + static_assert(test_ref<double>()); + assert((test_ref<double>())); - return 0; + return 0; } diff --git a/libcxx/test/std/utilities/optional/optional.specalg/swap.pass.cpp b/libcxx/test/std/utilities/optional/optional.specalg/swap.pass.cpp index 0da3a82..c757120 100644 --- a/libcxx/test/std/utilities/optional/optional.specalg/swap.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.specalg/swap.pass.cpp @@ -12,9 +12,10 @@ // template <class T> void swap(optional<T>& x, optional<T>& y) // noexcept(noexcept(x.swap(y))); +#include <cassert> +#include <memory> #include <optional> #include <type_traits> -#include <cassert> #include "test_macros.h" #include "archetypes.h" @@ -109,9 +110,82 @@ void test_swap_sfinae() { } } +#if TEST_STD_VER >= 26 +template <typename T> +constexpr bool test_swap_ref() { + { + optional<T&> opt1; + optional<T&> opt2; + static_assert(noexcept(swap(opt1, opt2)) == true); + assert(static_cast<bool>(opt1) == false); + assert(static_cast<bool>(opt2) == false); + swap(opt1, opt2); + assert(static_cast<bool>(opt1) == false); + assert(static_cast<bool>(opt2) == false); + } + { + T one{1}; + optional<T&> opt1(one); + optional<T&> opt2; + static_assert(noexcept(swap(opt1, opt2)) == true); + assert(static_cast<bool>(opt1) == true); + assert(*opt1 == 1); + assert(std::addressof(*opt1) == std::addressof(one)); + assert(static_cast<bool>(opt2) == false); + swap(opt1, opt2); + assert(static_cast<bool>(opt1) == false); + assert(static_cast<bool>(opt2) == true); + assert(*opt2 == 1); + assert(std::addressof(*opt2) == std::addressof(one)); + } + { + T two{2}; + optional<T&> opt1; + optional<T&> opt2(two); + static_assert(noexcept(swap(opt1, opt2)) == true); + assert(static_cast<bool>(opt1) == false); + assert(static_cast<bool>(opt2) == true); + assert(*opt2 == 2); + assert(std::addressof(*opt2) == std::addressof(two)); + swap(opt1, opt2); + assert(static_cast<bool>(opt1) == true); + assert(*opt1 == 2); + assert(std::addressof(*opt1) == std::addressof(two)); + assert(static_cast<bool>(opt2) == false); + } + { + T one{1}; + T two{2}; + optional<T&> opt1(one); + optional<T&> opt2(two); + static_assert(noexcept(swap(opt1, opt2)) == true); + assert(static_cast<bool>(opt1) == true); + assert(*opt1 == 1); + assert(std::addressof(*opt1) == std::addressof(one)); + assert(static_cast<bool>(opt2) == true); + assert(*opt2 == 2); + assert(std::addressof(*opt2) == std::addressof(two)); + swap(opt1, opt2); + assert(static_cast<bool>(opt1) == true); + assert(*opt1 == 2); + assert(std::addressof(*opt1) == std::addressof(two)); + assert(static_cast<bool>(opt2) == true); + assert(*opt2 == 1); + assert(std::addressof(*opt2) == std::addressof(one)); + } + return true; +} +#endif + int main(int, char**) { test_swap_sfinae(); +#if TEST_STD_VER >= 26 + static_assert(test_swap_ref<int>()); + static_assert(test_swap_ref<double>()); + test_swap_ref<int>(); + test_swap_ref<double>(); +#endif { optional<int> opt1; optional<int> opt2; diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.verify.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.verify.cpp index 12d7784..e58e760 100644 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.verify.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.verify.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// REQUIRES: std-at-least-c++23 +// REQUIRES: std-at-least-c++26 // <tuple> @@ -21,11 +21,6 @@ void test() { // expected-error@*:* {{static assertion failed}} - // Turns to an error since C++26 (Disallow Binding a Returned Glvalue to a Temporary https://wg21.link/P2748R5). -#if TEST_STD_VER >= 26 // expected-error@tuple:* {{returning reference to local temporary object}} -#else - // expected-warning@tuple:* {{returning reference to local temporary object}} -#endif std::ignore = std::make_from_tuple<const int&>(std::tuple<char>{}); } diff --git a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_greater/cmp_greater.pass.cpp b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_greater/cmp_greater.pass.cpp index 8b69ec6..f261166 100644 --- a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_greater/cmp_greater.pass.cpp +++ b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_greater/cmp_greater.pass.cpp @@ -17,6 +17,7 @@ #include <numeric> #include <tuple> #include <cassert> +#include <type_traits> #include "test_macros.h" diff --git a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less/cmp_less.pass.cpp b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less/cmp_less.pass.cpp index 2cc66eb..5a07835 100644 --- a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less/cmp_less.pass.cpp +++ b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less/cmp_less.pass.cpp @@ -18,6 +18,7 @@ #include <numeric> #include <tuple> #include <cassert> +#include <type_traits> #include "test_macros.h" diff --git a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less_equal/cmp_less_equal.pass.cpp b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less_equal/cmp_less_equal.pass.cpp index fb46980..079a2f7 100644 --- a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less_equal/cmp_less_equal.pass.cpp +++ b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less_equal/cmp_less_equal.pass.cpp @@ -17,6 +17,7 @@ #include <numeric> #include <tuple> #include <cassert> +#include <type_traits> #include "test_macros.h" diff --git a/libcxx/test/support/module.modulemap b/libcxx/test/support/module.modulemap new file mode 100644 index 0000000..75ae8c4 --- /dev/null +++ b/libcxx/test/support/module.modulemap @@ -0,0 +1,10 @@ + +module test_config { + module test_macros { textual header "test_macros.h" } +} + +module test { + module double_move_tracker { header "double_move_tracker.h" } + module test_allocator { header "test_allocator.h" } + module type_algorithms { header "type_algorithms.h" } +} diff --git a/libcxx/test/support/platform_support.h b/libcxx/test/support/platform_support.h index 99e60f6..b66fdff 100644 --- a/libcxx/test/support/platform_support.h +++ b/libcxx/test/support/platform_support.h @@ -48,7 +48,7 @@ # include <string.h> // strverscmp #endif -#if defined(_NEWLIB_VERSION) && defined(__STRICT_ANSI__) +#if _LIBCPP_LIBC_NEWLIB && defined(__STRICT_ANSI__) // Newlib provides this, but in the header it's under __STRICT_ANSI__ extern "C" { int mkstemp(char*); diff --git a/libcxx/test/support/test.support/test_check_assertion.pass.cpp b/libcxx/test/support/test.support/test_check_assertion.pass.cpp index 78e47b3..9d356ef 100644 --- a/libcxx/test/support/test.support/test_check_assertion.pass.cpp +++ b/libcxx/test/support/test.support/test_check_assertion.pass.cpp @@ -21,11 +21,11 @@ template <class Func> bool TestDeathTest( Outcome expected_outcome, DeathCause expected_cause, const char* stmt, Func&& func, const Matcher& matcher) { auto get_matcher = [&] { -#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG - return matcher; -#else +#if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE (void)matcher; return MakeAnyMatcher(); +#else + return matcher; #endif }; @@ -69,7 +69,7 @@ bool TestDeathTest( // clang-format on -#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG +#if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE DeathCause assertion_death_cause = DeathCause::VerboseAbort; #else DeathCause assertion_death_cause = DeathCause::Trap; @@ -99,7 +99,7 @@ int main(int, char**) { // Success -- assertion failure with a specific matcher. TEST_DEATH_TEST_MATCHES(Outcome::Success, assertion_death_cause, good_matcher, fail_assert()); -# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG +# if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE // Failure -- error message doesn't match. TEST_DEATH_TEST_MATCHES(Outcome::UnexpectedErrorMessage, assertion_death_cause, bad_matcher, fail_assert()); # endif diff --git a/libcxx/utils/ci/Dockerfile b/libcxx/utils/ci/Dockerfile deleted file mode 100644 index d22deec..0000000 --- a/libcxx/utils/ci/Dockerfile +++ /dev/null @@ -1,329 +0,0 @@ -# ===----------------------------------------------------------------------===## -# -# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -# See https://llvm.org/LICENSE.txt for license information. -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# -# ===----------------------------------------------------------------------===## -# -# This file defines the buildkite and github actions builder images. -# This images are tagged with <tag>. You can build both images using: -# -# TAG=<tag> docker compose build -# -# Or you can select a single image to build -# -# TAG=test docker compose build actions-builder -# -# The final images can be found at -# -# ghcr.io/libcxx/libcxx-linux-builder -# ghcr.io/libcxx/android-buildkite-builder -# -# Members of the github.com/libcxx/ organizations can push new images to the CI. -# This is done by GitHub actions in the https://github.com/libcxx/builders repo. -# -# ===----------------------------------------------------------------------===## -# Running the buildkite image -# ===----------------------------------------------------------------------===## -# -# To start a Buildkite Agent, run it as: -# $ docker run --env-file <secrets> -it $(docker build -q libcxx/utils/ci) -# -# The environment variables in `<secrets>` should be the ones necessary -# to run a BuildKite agent: -# -# BUILDKITE_AGENT_TOKEN=<token> -# -# If you're only looking to run the Docker image locally for debugging a -# build bot, see the `run-buildbot-container` script located in this directory. - -ARG ACTIONS_BASE_IMAGE - -# HACK: We set the base image in the docker-compose file depending on the final target (buildkite vs github actions). -# This means we have a much slower container build, but we can use the same Dockerfile for both targets. -ARG BASE_IMAGE -FROM $BASE_IMAGE AS builder-base - -# Changing this file causes a rebuild of the image in a GitHub action. -# However, it does not cause the CI runners to switch to that image -# automatically, that must be done by updating the SHA in the Github workflow -# file. The date uses the ISO format YYYY-MM-DD. -RUN echo "Last forced update executed on 2025-04-28." - -# Make sure apt-get doesn't try to prompt for stuff like our time zone, etc. -ENV DEBIAN_FRONTEND=noninteractive - -# populated in the docker-compose file -ARG GCC_HEAD_VERSION -ENV GCC_HEAD_VERSION=${GCC_HEAD_VERSION} - -# populated in the docker-compose file -ARG LLVM_HEAD_VERSION -ENV LLVM_HEAD_VERSION=${LLVM_HEAD_VERSION} - -# HACK: The github actions runner image already has sudo and requires its use. The buildkite base image does not. -# Reconcile this. -RUN <<EOF - apt-get update || true - apt-get install -y sudo || true - echo "ALL ALL = (ALL) NOPASSWD: ALL" | tee /etc/sudoers || true -EOF - -# Installing tzdata before other packages avoids the time zone prompts. -# These prompts seem to ignore DEBIAN_FRONTEND=noninteractive. -RUN sudo apt-get update \ - && sudo apt-get install -y \ - tzdata - -# Install various tools used by the build or the test suite -# TODO add ninja-build once 1.11 is available in Ubuntu, also remove the manual -# installation below. -RUN sudo apt-get update \ - && sudo apt-get install -y \ - bash \ - ccache \ - curl \ - gdb \ - git \ - gpg \ - language-pack-en \ - language-pack-fr \ - language-pack-ja \ - language-pack-ru \ - language-pack-zh-hans \ - libedit-dev \ - libncurses5-dev \ - libpython3-dev \ - libxml2-dev \ - lsb-release \ - make \ - python3 \ - python3-dev \ - python3-packaging \ - python3-setuptools \ - python3-psutil \ - software-properties-common \ - swig \ - unzip \ - uuid-dev \ - wget \ - xz-utils \ - && sudo rm -rf /var/lib/apt/lists/* - -RUN <<EOF - set -e - wget -qO /tmp/ninja.gz https://github.com/ninja-build/ninja/releases/latest/download/ninja-linux.zip - gunzip /tmp/ninja.gz - chmod a+x /tmp/ninja - sudo mv /tmp/ninja /usr/local/bin/ninja -EOF - - -# These two locales are not enabled by default so generate them -RUN <<EOF - set -e - printf "fr_CA ISO-8859-1\ncs_CZ ISO-8859-2" | sudo tee -a /etc/locale.gen - sudo mkdir /usr/local/share/i1en/ - printf "fr_CA ISO-8859-1\ncs_CZ ISO-8859-2" | sudo tee -a /usr/local/share/i1en/SUPPORTED - sudo locale-gen -EOF - -# Install Clang <latest>, <latest-1> and ToT, which are the ones we support. -# We also install <latest-2> because we need to support the "latest-1" of the -# current LLVM release branch, which is effectively the <latest-2> of the -# tip-of-trunk LLVM. For example, after branching LLVM 14 but before branching -# LLVM 15, we still need to have Clang 12 in this Docker image because the LLVM -# 14 release branch CI uses it. The tip-of-trunk CI will never use Clang 12, -# though. -RUN <<EOF - set -e - sudo apt-get update - wget https://apt.llvm.org/llvm.sh -O /tmp/llvm.sh - chmod +x /tmp/llvm.sh - sudo /tmp/llvm.sh $(($LLVM_HEAD_VERSION - 3)) all # for CI transitions - sudo /tmp/llvm.sh $(($LLVM_HEAD_VERSION - 2)) all # previous release - sudo /tmp/llvm.sh $(($LLVM_HEAD_VERSION - 1)) all # latest release - sudo /tmp/llvm.sh $LLVM_HEAD_VERSION all # current ToT - sudo apt-get install -y libomp5-$LLVM_HEAD_VERSION - sudo rm -rf /var/lib/apt/lists/* -EOF - -# Install the most recent GCC, like clang install the previous version as a transition. -RUN <<EOF - set -e - sudo git clone https://github.com/compiler-explorer/infra.git /tmp/ce-infra - (cd /tmp/ce-infra && sudo make ce) - # Current ToT, we do not guarantee any support in our support matrix. - sudo /tmp/ce-infra/bin/ce_install --enable nightly install compilers/c++/nightly/gcc trunk - sudo ln -s /opt/compiler-explorer/gcc-snapshot/bin/gcc /usr/bin/gcc-$GCC_HEAD_VERSION - sudo ln -s /opt/compiler-explorer/gcc-snapshot/bin/g++ /usr/bin/g++-$GCC_HEAD_VERSION - # The latest release. - sudo /tmp/ce-infra/bin/ce_install install compilers/c++/x86/gcc $((GCC_HEAD_VERSION - 1)).1.0 - sudo ln -s /opt/compiler-explorer/gcc-$((GCC_HEAD_VERSION - 1)).1.0/bin/gcc /usr/bin/gcc-$((GCC_HEAD_VERSION - 1)) - sudo ln -s /opt/compiler-explorer/gcc-$((GCC_HEAD_VERSION - 1)).1.0/bin/g++ /usr/bin/g++-$((GCC_HEAD_VERSION - 1)) - # For CI transitions. - sudo /tmp/ce-infra/bin/ce_install install compilers/c++/x86/gcc $((GCC_HEAD_VERSION - 2)).1.0 - sudo ln -s /opt/compiler-explorer/gcc-$((GCC_HEAD_VERSION - 2)).1.0/bin/gcc /usr/bin/gcc-$((GCC_HEAD_VERSION - 2)) - sudo ln -s /opt/compiler-explorer/gcc-$((GCC_HEAD_VERSION - 2)).1.0/bin/g++ /usr/bin/g++-$((GCC_HEAD_VERSION - 2)) - sudo rm -rf /tmp/ce-infra -EOF - -RUN <<EOF - # Install a recent CMake - set -e - wget https://github.com/Kitware/CMake/releases/download/v3.24.4/cmake-3.24.4-linux-x86_64.sh -O /tmp/install-cmake.sh - sudo bash /tmp/install-cmake.sh --prefix=/usr --exclude-subdir --skip-license - rm /tmp/install-cmake.sh -EOF - -# ===----------------------------------------------------------------------===## -# Android Builder Base Image -# ===----------------------------------------------------------------------===## - -FROM docker.io/library/ubuntu:jammy AS android-builder-base - -ARG ANDROID_CLANG_VERSION -ARG ANDROID_CLANG_PREBUILTS_COMMIT -ARG ANDROID_SYSROOT_COMMIT - -RUN apt-get update && apt-get install -y curl bzip2 git unzip - -# Install the Android platform tools (e.g. adb) into /opt/android/sdk. -RUN <<EOF - set -e - mkdir -p /opt/android/sdk - cd /opt/android/sdk - curl -LO https://dl.google.com/android/repository/platform-tools-latest-linux.zip - unzip platform-tools-latest-linux.zip - rm platform-tools-latest-linux.zip -EOF - -# Install the current Android compiler. Specify the prebuilts commit to retrieve -# this compiler version even after it's removed from HEAD. - -ENV ANDROID_CLANG_VERSION=$ANDROID_CLANG_VERSION -ENV ANDROID_CLANG_PREBUILTS_COMMIT=$ANDROID_CLANG_PREBUILTS_COMMIT -RUN <<EOF - set -e - git clone --filter=blob:none --sparse \ - https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86 \ - /opt/android/clang - git -C /opt/android/clang checkout ${ANDROID_CLANG_PREBUILTS_COMMIT} - git -C /opt/android/clang sparse-checkout add clang-${ANDROID_CLANG_VERSION} - rm -fr /opt/android/clang/.git - ln -sf /opt/android/clang/clang-${ANDROID_CLANG_VERSION} /opt/android/clang/clang-current - # The "git sparse-checkout" and "ln" commands succeed even if nothing was - # checked out, so use this "ls" command to fix that. - ls /opt/android/clang/clang-current/bin/clang -EOF - -# Install an Android sysroot. New Android sysroots are available at -# https://android.googlesource.com/platform/prebuilts/ndk/+/refs/heads/mirror-goog-main-ndk/platform/sysroot. - -ENV ANDROID_SYSROOT_COMMIT=$ANDROID_SYSROOT_COMMIT -RUN <<EOF - set -e - mkdir -p /opt/android/ndk - cd /opt/android/ndk - git clone --filter=blob:none https://android.googlesource.com/platform/prebuilts/ndk tmp - git -C tmp checkout ${ANDROID_SYSROOT_COMMIT} - mv tmp/platform/sysroot . - rm -rf tmp -EOF - -# ===----------------------------------------------------------------------===## -# Buildkite Builder Image -# ===----------------------------------------------------------------------===## -# -# IMAGE: ghcr.io/libcxx/buildkite-builder. -# -FROM builder-base AS buildkite-builder - -# Create the libcxx-builder user, regardless of if we use it or not -RUN sudo useradd --create-home libcxx-builder - -USER libcxx-builder -WORKDIR /home/libcxx-builder - -# Install the Buildkite agent and dependencies. This must be done as non-root -# for the Buildkite agent to be installed in a path where we can find it. -RUN <<EOF - set -e - cd /home/libcxx-builder - curl -sL https://raw.githubusercontent.com/buildkite/agent/main/install.sh -o /tmp/install-agent.sh - bash /tmp/install-agent.sh - rm /tmp/install-agent.sh - echo "tags=\"queue=libcxx-builders,arch=$(uname -m),os=linux\"" \ - >> /home/libcxx-builder/.buildkite-agent/buildkite-agent.cfg -EOF - -USER libcxx-builder -WORKDIR /home/libcxx-builder - -ENV PATH="${PATH}:/home/libcxx-builder/.buildkite-agent/bin" - -CMD ["buildkite-agent", "start"] - -# ===----------------------------------------------------------------------===## -# Android Buildkite Builder Image -# ===----------------------------------------------------------------------===## -# -# IMAGE: ghcr.io/libcxx/android-buildkite-builder. -# -FROM buildkite-builder AS android-buildkite-builder - -COPY --from=android-builder-base /opt/android /opt/android -COPY ./vendor/android/container-setup.sh /opt/android/container-setup.sh - -ENV PATH="/opt/android/sdk/platform-tools:${PATH}" - -USER root - -# Install Docker -RUN <<EOF - set -e - curl -fsSL https://get.docker.com -o /tmp/get-docker.sh - sh /tmp/get-docker.sh - rm /tmp/get-docker.sh - - # Install Docker. Mark the binary setuid so it can be run without prefixing it - # with sudo. Adding the container user to the docker group doesn't work because - # /var/run/docker.sock is owned by the host's docker GID, not the container's - # docker GID. - chmod u+s /usr/bin/docker -EOF - -USER libcxx-builder -WORKDIR /home/libcxx-builder - -# Reset the configuration, we pass the configuration via the environment. -RUN cp /home/libcxx-builder/.buildkite-agent/buildkite-agent.dist.cfg \ - /home/libcxx-builder/.buildkite-agent/buildkite-agent.cfg - -# Modify the Buildkite agent cmdline to do Android setup stuff first. -CMD /opt/android/container-setup.sh && buildkite-agent start - -# ===----------------------------------------------------------------------===## -# Github Actions Builder Image -# ===----------------------------------------------------------------------===## -# -# IMAGE: ghcr.io/libcxx/actions-builder. -# -FROM $ACTIONS_BASE_IMAGE AS actions-builder - -ARG GITHUB_RUNNER_VERSION - -RUN useradd gha -u 1001 -m -s /bin/bash -RUN adduser gha sudo -RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers -WORKDIR /home/gha -USER gha - -ENV RUNNER_MANUALLY_TRAP_SIG=1 -ENV ACTIONS_RUNNER_PRINT_LOG_TO_STDOUT=1 -RUN mkdir actions-runner && \ - cd actions-runner && \ - curl -O -L https://github.com/actions/runner/releases/download/v$GITHUB_RUNNER_VERSION/actions-runner-linux-x64-$GITHUB_RUNNER_VERSION.tar.gz && \ - tar xzf ./actions-runner-linux-x64-$GITHUB_RUNNER_VERSION.tar.gz && \ - rm ./actions-runner-linux-x64-$GITHUB_RUNNER_VERSION.tar.gz diff --git a/libcxx/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml index 2ac69c3..1938d9a 100644 --- a/libcxx/utils/ci/buildkite-pipeline.yml +++ b/libcxx/utils/ci/buildkite-pipeline.yml @@ -37,6 +37,9 @@ steps: steps: - label: AArch64 command: libcxx/utils/ci/run-buildbot aarch64 + env: + CC: cc + CXX: c++ agents: queue: libcxx-builders-linaro-arm arch: aarch64 @@ -44,6 +47,9 @@ steps: - label: AArch64 -fno-exceptions command: libcxx/utils/ci/run-buildbot aarch64-no-exceptions + env: + CC: cc + CXX: c++ agents: queue: libcxx-builders-linaro-arm arch: aarch64 @@ -51,6 +57,9 @@ steps: - label: Armv8 command: libcxx/utils/ci/run-buildbot armv8 + env: + CC: cc + CXX: c++ agents: queue: libcxx-builders-linaro-arm arch: armv8l @@ -58,6 +67,9 @@ steps: - label: Armv8 -fno-exceptions command: libcxx/utils/ci/run-buildbot armv8-no-exceptions + env: + CC: cc + CXX: c++ agents: queue: libcxx-builders-linaro-arm arch: armv8l @@ -65,6 +77,9 @@ steps: - label: Armv7 command: libcxx/utils/ci/run-buildbot armv7 + env: + CC: cc + CXX: c++ agents: queue: libcxx-builders-linaro-arm arch: armv8l @@ -72,6 +87,9 @@ steps: - label: Armv7 -fno-exceptions command: libcxx/utils/ci/run-buildbot armv7-no-exceptions + env: + CC: cc + CXX: c++ agents: queue: libcxx-builders-linaro-arm arch: armv8l @@ -79,6 +97,9 @@ steps: - label: Armv7-M picolibc command: libcxx/utils/ci/run-buildbot armv7m-picolibc + env: + CC: cc + CXX: c++ agents: queue: libcxx-builders-linaro-arm arch: aarch64 @@ -86,6 +107,9 @@ steps: - label: Armv7-M picolibc -fno-exceptions command: libcxx/utils/ci/run-buildbot armv7m-picolibc-no-exceptions + env: + CC: cc + CXX: c++ agents: queue: libcxx-builders-linaro-arm arch: aarch64 @@ -131,6 +155,9 @@ steps: steps: - label: Android 5.0, x86 NDK command: libcxx/utils/ci/run-buildbot android-ndk-21-def-x86 + env: + CC: /opt/android/clang/clang-current/bin/clang + CXX: /opt/android/clang/clang-current/bin/clang++ agents: queue: libcxx-builders os: android @@ -138,6 +165,9 @@ steps: - label: Android 13, x86_64 NDK command: libcxx/utils/ci/run-buildbot android-ndk-33-goog-x86_64 + env: + CC: /opt/android/clang/clang-current/bin/clang + CXX: /opt/android/clang/clang-current/bin/clang++ agents: queue: libcxx-builders os: android diff --git a/libcxx/utils/ci/docker-compose.yml b/libcxx/utils/ci/docker-compose.yml deleted file mode 100644 index 9367a8f..0000000 --- a/libcxx/utils/ci/docker-compose.yml +++ /dev/null @@ -1,40 +0,0 @@ -x-versions: &compiler_versions - GCC_HEAD_VERSION: 16 - LLVM_HEAD_VERSION: 22 - -x-image-versions: &image_versions - BASE_IMAGE: docker.io/library/ubuntu:jammy - ACTIONS_BASE_IMAGE: ghcr.io/llvm/libcxx-linux-builder-base:77cb0980bcc2675b27d08141526939423fa0be76 - -services: - builder-base: - image: ghcr.io/llvm/libcxx-linux-builder-base:${TAG} - build: - context: . - dockerfile: Dockerfile - target: builder-base - args: - <<: [*image_versions, *compiler_versions] - - actions-builder: - image: ghcr.io/llvm/libcxx-linux-builder:${TAG} - build: - context: . - dockerfile: Dockerfile - target: actions-builder - args: - GITHUB_RUNNER_VERSION: "2.329.0" - <<: [*image_versions, *compiler_versions] - - android-buildkite-builder: - image: ghcr.io/llvm/libcxx-android-builder:${TAG} - build: - context: . - dockerfile: Dockerfile - target: android-buildkite-builder - args: - BASE_IMAGE: docker.io/library/ubuntu:noble - ANDROID_CLANG_VERSION: r563880 - ANDROID_CLANG_PREBUILTS_COMMIT: 6ae4184bb8706f9731569b9a0a82be3fcdcb951c - ANDROID_SYSROOT_COMMIT: f8b85cc5262c6e5cbc9a92c1bab2b18b32a4c63f - <<: [*image_versions, *compiler_versions] diff --git a/libcxx/utils/ci/docker/android-builder.dockerfile b/libcxx/utils/ci/docker/android-builder.dockerfile new file mode 100644 index 0000000..9c5d504 --- /dev/null +++ b/libcxx/utils/ci/docker/android-builder.dockerfile @@ -0,0 +1,114 @@ +# ===----------------------------------------------------------------------===## +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# ===----------------------------------------------------------------------===## +# +# This file defines the image we use to run Android testing on Buildkite. +# From the root of the monorepo, this image can be built with: +# +# $ docker build --file libcxx/utils/ci/docker/android-builder.dockerfile \ +# --build-arg BASE_IMAGE_VERSION=<sha> \ +# --build-arg ANDROID_CLANG_VERSION=<version> \ +# --build-arg ANDROID_CLANG_PREBUILTS_COMMIT=<sha> \ +# --build-arg ANDROID_SYSROOT_COMMIT=<sha> . +# +# This image also gets built on every push to `main` that modifies these Docker +# files, and can be found at ghcr.io/llvm/libcxx-android-builder. +# +# To run the image and start a Buildkite Agent, run it as: +# +# $ docker run --env-file <secrets> -it ghcr.io/llvm/libcxx-android-builder:latest +# +# The environment variables in `<secrets>` should be the ones necessary +# to run a BuildKite agent: +# +# BUILDKITE_AGENT_TOKEN=<token> + +ARG BASE_IMAGE_VERSION +FROM ghcr.io/llvm/libcxx-linux-builder-base:${BASE_IMAGE_VERSION} + +ARG ANDROID_CLANG_VERSION +ARG ANDROID_CLANG_PREBUILTS_COMMIT +ARG ANDROID_SYSROOT_COMMIT + +# Install the Android platform tools (e.g. adb) into /opt/android/sdk. +RUN <<EOF + set -e + mkdir -p /opt/android/sdk + cd /opt/android/sdk + curl -LO https://dl.google.com/android/repository/platform-tools-latest-linux.zip + unzip platform-tools-latest-linux.zip + rm platform-tools-latest-linux.zip +EOF + +# Install the current Android compiler. Specify the prebuilts commit to retrieve +# this compiler version even after it's removed from HEAD. +ENV ANDROID_CLANG_VERSION=$ANDROID_CLANG_VERSION +ENV ANDROID_CLANG_PREBUILTS_COMMIT=$ANDROID_CLANG_PREBUILTS_COMMIT +RUN <<EOF + set -e + git clone --filter=blob:none --sparse \ + https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86 \ + /opt/android/clang + git -C /opt/android/clang checkout ${ANDROID_CLANG_PREBUILTS_COMMIT} + git -C /opt/android/clang sparse-checkout add clang-${ANDROID_CLANG_VERSION} + rm -fr /opt/android/clang/.git + ln -sf /opt/android/clang/clang-${ANDROID_CLANG_VERSION} /opt/android/clang/clang-current + # The "git sparse-checkout" and "ln" commands succeed even if nothing was + # checked out, so use this "ls" command to fix that. + ls /opt/android/clang/clang-current/bin/clang +EOF + +# Install an Android sysroot. New Android sysroots are available at +# https://android.googlesource.com/platform/prebuilts/ndk/+/refs/heads/mirror-goog-main-ndk/platform/sysroot. +ENV ANDROID_SYSROOT_COMMIT=$ANDROID_SYSROOT_COMMIT +RUN <<EOF + set -e + mkdir -p /opt/android/ndk + cd /opt/android/ndk + git clone --filter=blob:none https://android.googlesource.com/platform/prebuilts/ndk tmp + git -C tmp checkout ${ANDROID_SYSROOT_COMMIT} + mv tmp/platform/sysroot . + rm -rf tmp +EOF + +# Create the libcxx-builder user +RUN sudo useradd --create-home libcxx-builder +WORKDIR /home/libcxx-builder + +# Install the Buildkite agent and dependencies. This must be done as non-root +# for the Buildkite agent to be installed in a path where we can find it. +# +# Note that we don't set up the configuration file here, since the configuration +# is passed via the environment. +RUN <<EOF + set -e + cd /home/libcxx-builder + curl -sL https://raw.githubusercontent.com/buildkite/agent/main/install.sh -o /tmp/install-agent.sh + bash /tmp/install-agent.sh + rm /tmp/install-agent.sh +EOF +ENV PATH="${PATH}:/home/libcxx-builder/.buildkite-agent/bin" + +# Install Docker +RUN <<EOF + set -e + curl -fsSL https://get.docker.com -o /tmp/get-docker.sh + sh /tmp/get-docker.sh + rm /tmp/get-docker.sh + + # Install Docker. Mark the binary setuid so it can be run without prefixing it + # with sudo. Adding the container user to the docker group doesn't work because + # /var/run/docker.sock is owned by the host's docker GID, not the container's + # docker GID. + chmod u+s /usr/bin/docker +EOF + +# Setup the Buildkite agent command line to do Android setup stuff first. +USER libcxx-builder +COPY libcxx/utils/ci/vendor/android/container-setup.sh /opt/android/container-setup.sh +ENV PATH="/opt/android/sdk/platform-tools:${PATH}" +CMD /opt/android/container-setup.sh && buildkite-agent start diff --git a/libcxx/utils/ci/docker/docker-compose.yml b/libcxx/utils/ci/docker/docker-compose.yml new file mode 100644 index 0000000..74df3e49 --- /dev/null +++ b/libcxx/utils/ci/docker/docker-compose.yml @@ -0,0 +1,38 @@ +# +# This docker compose file allows building the various Docker images we use for +# libc++'s CI. It encodes the versions of various tools included in these images. +# +# Images can be built with: +# +# $ docker compose --file libcxx/utils/ci/docker/docker-compose.yml build <image-name> +# + +services: + libcxx-linux-builder-base: + image: ghcr.io/llvm/libcxx-linux-builder-base:${TAG:-latest} + build: + context: ../../../.. # monorepo root + dockerfile: libcxx/utils/ci/docker/linux-builder-base.dockerfile + args: + GCC_HEAD_VERSION: 16 + LLVM_HEAD_VERSION: 22 + + libcxx-linux-builder: + image: ghcr.io/llvm/libcxx-linux-builder:${TAG:-latest} + build: + context: ../../../.. # monorepo root + dockerfile: libcxx/utils/ci/docker/linux-builder.dockerfile + args: + BASE_IMAGE_VERSION: 825943e06f840710177e5514c4f61c9e73660c44 + GITHUB_RUNNER_VERSION: 2.329.0 + + libcxx-android-builder: + image: ghcr.io/llvm/libcxx-android-builder:${TAG:-latest} + build: + context: ../../../.. # monorepo root + dockerfile: libcxx/utils/ci/docker/android-builder.dockerfile + args: + BASE_IMAGE_VERSION: 825943e06f840710177e5514c4f61c9e73660c44 + ANDROID_CLANG_VERSION: r563880 + ANDROID_CLANG_PREBUILTS_COMMIT: 6ae4184bb8706f9731569b9a0a82be3fcdcb951c + ANDROID_SYSROOT_COMMIT: f8b85cc5262c6e5cbc9a92c1bab2b18b32a4c63f diff --git a/libcxx/utils/ci/docker/linux-builder-base.dockerfile b/libcxx/utils/ci/docker/linux-builder-base.dockerfile new file mode 100644 index 0000000..8a8a6e3 --- /dev/null +++ b/libcxx/utils/ci/docker/linux-builder-base.dockerfile @@ -0,0 +1,141 @@ +# ===----------------------------------------------------------------------===## +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# ===----------------------------------------------------------------------===## +# +# This file defines the base image we use for Linux testing using Github Actions. +# From the root of the monorepo, this image can be built with: +# +# $ docker build --file libcxx/utils/ci/docker/linux-builder-base.dockerfile \ +# --build-arg GCC_HEAD_VERSION=<version> \ +# --build-arg LLVM_HEAD_VERSION=<version> . +# +# This image also gets built on every push to `main` that modifies these Docker +# files, and can be found at ghcr.io/libcxx/libcxx-linux-builder-base . + +FROM docker.io/library/ubuntu:noble + +# Changing this file causes a rebuild of the image in a GitHub action. However, it does not cause +# the CI runners to switch to that image automatically, that must be done by updating the image used +# by the libc++ self-hosted runners in llvm-zorg. The date uses the ISO format YYYY-MM-DD. +RUN echo "Last forced update executed on 2025-11-11." + +# Make sure apt-get doesn't try to prompt for stuff like our time zone, etc. +ENV DEBIAN_FRONTEND=noninteractive + +# populated in the docker-compose file +ARG GCC_HEAD_VERSION +ENV GCC_HEAD_VERSION=${GCC_HEAD_VERSION} + +# populated in the docker-compose file +ARG LLVM_HEAD_VERSION +ENV LLVM_HEAD_VERSION=${LLVM_HEAD_VERSION} + +# Install sudo and setup passwordless sudo. +RUN <<EOF + apt-get update || true + apt-get install -y sudo || true + echo "ALL ALL = (ALL) NOPASSWD: ALL" | tee /etc/sudoers || true +EOF + +# Installing tzdata before other packages avoids the time zone prompts. +# These prompts seem to ignore DEBIAN_FRONTEND=noninteractive. +RUN sudo apt-get update \ + && sudo apt-get install -y \ + tzdata + +# Install various tools used by the build or the test suite +# TODO add ninja-build once 1.11 is available in Ubuntu, also remove the manual +# installation below. +RUN sudo apt-get update \ + && sudo apt-get install -y \ + bash \ + bzip2 \ + ccache \ + curl \ + gdb \ + git \ + gpg \ + language-pack-en \ + language-pack-fr \ + language-pack-ja \ + language-pack-ru \ + language-pack-zh-hans \ + libedit-dev \ + libncurses5-dev \ + libpython3-dev \ + libxml2-dev \ + lsb-release \ + make \ + ninja-build \ + python3 \ + python3-dev \ + python3-packaging \ + python3-setuptools \ + python3-psutil \ + software-properties-common \ + swig \ + unzip \ + uuid-dev \ + wget \ + xz-utils \ + && sudo rm -rf /var/lib/apt/lists/* + +# These two locales are not enabled by default so generate them +RUN <<EOF + set -e + printf "fr_CA ISO-8859-1\ncs_CZ ISO-8859-2" | sudo tee -a /etc/locale.gen + sudo mkdir /usr/local/share/i1en/ + printf "fr_CA ISO-8859-1\ncs_CZ ISO-8859-2" | sudo tee -a /usr/local/share/i1en/SUPPORTED + sudo locale-gen +EOF + +# Install Clang <latest>, <latest-1> and ToT, which are the ones we support. +# We also install <latest-2> because we need to support the "latest-1" of the +# current LLVM release branch, which is effectively the <latest-2> of the +# tip-of-trunk LLVM. For example, after branching LLVM 14 but before branching +# LLVM 15, we still need to have Clang 12 in this Docker image because the LLVM +# 14 release branch CI uses it. The tip-of-trunk CI will never use Clang 12, +# though. +RUN <<EOF + set -e + sudo apt-get update + wget https://apt.llvm.org/llvm.sh -O /tmp/llvm.sh + chmod +x /tmp/llvm.sh + sudo /tmp/llvm.sh $(($LLVM_HEAD_VERSION - 3)) all # for CI transitions + sudo /tmp/llvm.sh $(($LLVM_HEAD_VERSION - 2)) all # previous release + sudo /tmp/llvm.sh $(($LLVM_HEAD_VERSION - 1)) all # latest release + sudo /tmp/llvm.sh $LLVM_HEAD_VERSION all # current ToT + sudo rm -rf /var/lib/apt/lists/* +EOF + +# Install the most recent GCC, like clang install the previous version as a transition. +RUN <<EOF + set -e + sudo git clone https://github.com/compiler-explorer/infra.git /tmp/ce-infra + (cd /tmp/ce-infra && sudo make ce) + # Current ToT, we do not guarantee any support in our support matrix. + sudo /tmp/ce-infra/bin/ce_install --enable nightly install compilers/c++/nightly/gcc trunk + sudo ln -s /opt/compiler-explorer/gcc-snapshot/bin/gcc /usr/bin/gcc-$GCC_HEAD_VERSION + sudo ln -s /opt/compiler-explorer/gcc-snapshot/bin/g++ /usr/bin/g++-$GCC_HEAD_VERSION + # The latest release. + sudo /tmp/ce-infra/bin/ce_install install compilers/c++/x86/gcc $((GCC_HEAD_VERSION - 1)).1.0 + sudo ln -s /opt/compiler-explorer/gcc-$((GCC_HEAD_VERSION - 1)).1.0/bin/gcc /usr/bin/gcc-$((GCC_HEAD_VERSION - 1)) + sudo ln -s /opt/compiler-explorer/gcc-$((GCC_HEAD_VERSION - 1)).1.0/bin/g++ /usr/bin/g++-$((GCC_HEAD_VERSION - 1)) + # For CI transitions. + sudo /tmp/ce-infra/bin/ce_install install compilers/c++/x86/gcc $((GCC_HEAD_VERSION - 2)).1.0 + sudo ln -s /opt/compiler-explorer/gcc-$((GCC_HEAD_VERSION - 2)).1.0/bin/gcc /usr/bin/gcc-$((GCC_HEAD_VERSION - 2)) + sudo ln -s /opt/compiler-explorer/gcc-$((GCC_HEAD_VERSION - 2)).1.0/bin/g++ /usr/bin/g++-$((GCC_HEAD_VERSION - 2)) + sudo rm -rf /tmp/ce-infra +EOF + +RUN <<EOF + # Install a recent CMake + set -e + wget https://github.com/Kitware/CMake/releases/download/v3.24.4/cmake-3.24.4-linux-x86_64.sh -O /tmp/install-cmake.sh + sudo bash /tmp/install-cmake.sh --prefix=/usr --exclude-subdir --skip-license + rm /tmp/install-cmake.sh +EOF diff --git a/libcxx/utils/ci/docker/linux-builder.dockerfile b/libcxx/utils/ci/docker/linux-builder.dockerfile new file mode 100644 index 0000000..d6a878b --- /dev/null +++ b/libcxx/utils/ci/docker/linux-builder.dockerfile @@ -0,0 +1,38 @@ +# ===----------------------------------------------------------------------===## +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# ===----------------------------------------------------------------------===## +# +# This file defines the image we use for Linux testing using Github Actions. +# From the root of the monorepo, this image can be built with: +# +# $ docker build --file libcxx/utils/ci/docker/linux-builder.dockerfile \ +# --build-arg BASE_IMAGE_VERSION=<sha> \ +# --build-arg GITHUB_RUNNER_VERSION=<version> . +# +# This image also gets built on every push to `main` that modifies these Docker +# files, and can be found at ghcr.io/llvm/libcxx-linux-builder. + +ARG BASE_IMAGE_VERSION +FROM ghcr.io/llvm/libcxx-linux-builder-base:${BASE_IMAGE_VERSION} + +ARG GITHUB_RUNNER_VERSION + +# Setup the user +RUN useradd gha -u 1001 -m -s /bin/bash +RUN adduser gha sudo +RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers +WORKDIR /home/gha +USER gha + +# Install the Github Actions runner +ENV RUNNER_MANUALLY_TRAP_SIG=1 +ENV ACTIONS_RUNNER_PRINT_LOG_TO_STDOUT=1 +RUN mkdir actions-runner && \ + cd actions-runner && \ + curl -O -L https://github.com/actions/runner/releases/download/v$GITHUB_RUNNER_VERSION/actions-runner-linux-x64-$GITHUB_RUNNER_VERSION.tar.gz && \ + tar xzf ./actions-runner-linux-x64-$GITHUB_RUNNER_VERSION.tar.gz && \ + rm ./actions-runner-linux-x64-$GITHUB_RUNNER_VERSION.tar.gz diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot index d265ddd..b8ff947 100755 --- a/libcxx/utils/ci/run-buildbot +++ b/libcxx/utils/ci/run-buildbot @@ -30,17 +30,41 @@ ${PROGNAME} [options] <BUILDER> Environment variables CC The C compiler to use, this value is used by CMake. This - variable is optional. + variable is mandatory. CXX The C++ compiler to use, this value is used by CMake. This - variable is optional. - -CLANG_FORMAT The clang-format binary to use when generating the format - ignore list. + variable is mandatory. +CCACHE The ccache binary to use. This variable is optional and is only + used by the bootstrapping build. EOF } +function step() { + endstep + set +x + if [[ ! -z ${GITHUB_ACTIONS+x} ]]; then + echo "::group::$1" + export IN_GROUP=1 + else + echo "--- $1" + fi + set -x +} + +function endstep() { + set +x + if [[ ! -z ${GITHUB_ACTIONS+x} ]] && [[ ! -z ${IN_GROUP+x} ]]; then + echo "::endgroup::" + unset IN_GROUP + fi + set -x +} + +function error() { + echo "::error::$1" +} + if [[ $# == 0 ]]; then usage exit 0 @@ -71,30 +95,22 @@ MONOREPO_ROOT="${MONOREPO_ROOT:="$(git rev-parse --show-toplevel)"}" BUILD_DIR="${BUILD_DIR:=${MONOREPO_ROOT}/build/${BUILDER}}" INSTALL_DIR="${BUILD_DIR}/install" -function step() { - endstep - set +x - if [[ ! -z ${GITHUB_ACTIONS+x} ]]; then - echo "::group::$1" - export IN_GROUP=1 - else - echo "--- $1" - fi - set -x -} +if [ -z ${CC+x} ]; then + error "Environment variable CC must be defined" + exit 1 +fi -function endstep() { - set +x - if [[ ! -z ${GITHUB_ACTIONS+x} ]] && [[ ! -z ${IN_GROUP+x} ]]; then - echo "::endgroup::" - unset IN_GROUP - fi - set -x -} +if [ -z ${CXX+x} ]; then + error "Environment variable CXX must be defined" + exit 1 +fi -function error() { - echo "::error::$1" -} +# Print the version of a few tools to aid diagnostics in some cases +step "Diagnose tools in use" +cmake --version +ninja --version +${CC} --version +${CXX} --version function clean() { rm -rf "${BUILD_DIR}" @@ -127,11 +143,7 @@ function generate-cmake() { } function generate-cmake-libcxx-win() { - generate-cmake-base \ - -DLLVM_ENABLE_RUNTIMES="libcxx" \ - -DCMAKE_C_COMPILER=clang-cl \ - -DCMAKE_CXX_COMPILER=clang-cl \ - "${@}" + generate-cmake-base -DLLVM_ENABLE_RUNTIMES="libcxx" "${@}" } function generate-cmake-android() { @@ -205,6 +217,7 @@ function test-armv7m-picolibc() { -DLIBUNWIND_TEST_CONFIG="armv7m-picolibc-libunwind.cfg.in" \ -DCMAKE_C_FLAGS="${flags}" \ -DCMAKE_CXX_FLAGS="${flags}" \ + -DRUNTIMES_USE_LIBC=picolibc \ "${@}" step "Installing compiler-rt" @@ -215,12 +228,6 @@ function test-armv7m-picolibc() { check-runtimes } -# Print the version of a few tools to aid diagnostics in some cases -step "Diagnose tools in use" -cmake --version -ninja --version -if [ ! -z "${CXX}" ]; then ${CXX} --version; fi - case "${BUILDER}" in check-generated-output) # `! foo` doesn't work properly with `set -e`, use `! foo || false` instead. @@ -357,20 +364,25 @@ generic-ubsan) bootstrapping-build) clean + if [ ! -z ${CCACHE+x} ]; then + COMPILER_LAUNCHER="-DCMAKE_CXX_COMPILER_LAUNCHER=${CCACHE}" + fi + step "Generating CMake" cmake \ -S "${MONOREPO_ROOT}/llvm" \ -B "${BUILD_DIR}" \ -GNinja \ - -DCMAKE_CXX_COMPILER_LAUNCHER="ccache" \ + ${COMPILER_LAUNCHER} \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \ -DLLVM_ENABLE_PROJECTS="clang;lldb" \ - -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \ + -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind;compiler-rt" \ -DLLVM_RUNTIME_TARGETS="$(${CXX} --print-target-triple)" \ -DLLVM_HOST_TRIPLE="$(${CXX} --print-target-triple)" \ -DLLVM_TARGETS_TO_BUILD="host" \ -DRUNTIMES_BUILD_ALLOW_DARWIN=ON \ + -DCOMPILER_RT_INCLUDE_TESTS=OFF \ -DLLVM_ENABLE_ASSERTIONS=ON \ -DLLVM_LIT_ARGS="-sv --xunit-xml-output test-results.xml --timeout=1500 --time-tests" @@ -689,14 +701,6 @@ mingw-static) -DLIBUNWIND_ENABLE_SHARED=OFF check-runtimes ;; -mingw-dll-i686) - clean - generate-cmake \ - -DCMAKE_C_COMPILER=i686-w64-mingw32-clang \ - -DCMAKE_CXX_COMPILER=i686-w64-mingw32-clang++ \ - -C "${MONOREPO_ROOT}/libcxx/cmake/caches/MinGW.cmake" - check-runtimes -;; mingw-incomplete-sysroot) # When bringing up a new cross compiler from scratch, we build # libunwind/libcxx in a setup where the toolchain is incomplete and @@ -741,10 +745,6 @@ android-ndk-*) fi ARCH=$(arch_of_emu_img ${ANDROID_EMU_IMG}) - # Use the Android compiler by default. - export CC=${CC:-/opt/android/clang/clang-current/bin/clang} - export CXX=${CXX:-/opt/android/clang/clang-current/bin/clang++} - # The NDK libc++_shared.so is always built against the oldest supported API # level. When tests are run against a device with a newer API level, test # programs can be built for any supported API level, but building for the diff --git a/libcxx/utils/ci/run-buildbot-container b/libcxx/utils/ci/run-buildbot-container index 33a00a9c..fa83d1d 100755 --- a/libcxx/utils/ci/run-buildbot-container +++ b/libcxx/utils/ci/run-buildbot-container @@ -26,6 +26,6 @@ if [[ ! -d "${MONOREPO_ROOT}/libcxx/utils/ci" ]]; then echo "Was unable to find the root of the LLVM monorepo; are you running from within the monorepo?" exit 1 fi -docker pull ghcr.io/llvm/libcxx-linux-builder:b060022103f551d8ca1dad84122ef73927c86512 -docker run -it --volume "${MONOREPO_ROOT}:/llvm" --workdir "/llvm" --cap-add=SYS_PTRACE ghcr.io/llvm/libcxx-linux-builder:b060022103f551d8ca1dad84122ef73927c86512 \ +docker pull ghcr.io/llvm/libcxx-linux-builder:d6b22a347f813cf4a9832627323a43074f57bbcf +docker run -it --volume "${MONOREPO_ROOT}:/llvm" --workdir "/llvm" --cap-add=SYS_PTRACE ghcr.io/llvm/libcxx-linux-builder:d6b22a347f813cf4a9832627323a43074f57bbcf \ bash -c 'git config --global --add safe.directory /llvm ; exec bash' diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py index 22209f5..0802f86 100644 --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -14,7 +14,7 @@ from typing import ( ) import functools import json -from libcxx.header_information import module_c_headers, module_headers, header_restrictions, headers_not_available, libcxx_root +from libcxx.header_information import headers_not_available def get_libcxx_paths(): @@ -1017,6 +1017,7 @@ feature_test_macros = [ "c++17": 201606, "c++20": 202106, # P2231R1 Missing constexpr in std::optional and std::variant "c++23": 202110, # P0798R8 Monadic operations for std::optional + LWG3621 Remove feature-test macro __cpp_lib_monadic_optional + "c++26": 202506, # P2988R12: std::optional<T&> }, "headers": ["optional"], }, diff --git a/libcxx/utils/libcxx/test/config.py b/libcxx/utils/libcxx/test/config.py index 0840c46..00fab6a 100644 --- a/libcxx/utils/libcxx/test/config.py +++ b/libcxx/utils/libcxx/test/config.py @@ -22,6 +22,7 @@ def _appendToSubstitution(substitutions, key, value): def configure(parameters, features, config, lit_config): note = lambda s: lit_config.note("({}) {}".format(config.name, s)) + debug = lambda s: lit_config.dbg("({}) {}".format(config.name, s)) config.environment = dict(os.environ) # Apply the actions supplied by parameters to the configuration first, since @@ -31,25 +32,23 @@ def configure(parameters, features, config, lit_config): actions = param.getActions(config, lit_config.params) for action in actions: action.applyTo(config) - if lit_config.debug: - note( - "Applied '{}' as a result of parameter '{}'".format( - action.pretty(config, lit_config.params), - param.pretty(config, lit_config.params), - ) + debug( + "Applied '{}' as a result of parameter '{}'".format( + action.pretty(config, lit_config.params), + param.pretty(config, lit_config.params), ) + ) # Then, apply the automatically-detected features. for feature in features: actions = feature.getActions(config) for action in actions: action.applyTo(config) - if lit_config.debug: - note( - "Applied '{}' as a result of implicitly detected feature '{}'".format( - action.pretty(config, lit_config.params), feature.pretty(config) - ) + debug( + "Applied '{}' as a result of implicitly detected feature '{}'".format( + action.pretty(config, lit_config.params), feature.pretty(config) ) + ) # Print the basic substitutions for sub in ("%{cxx}", "%{flags}", "%{compile_flags}", "%{link_flags}", "%{benchmark_flags}", "%{exec}"): diff --git a/libcxx/utils/libcxx/test/dsl.py b/libcxx/utils/libcxx/test/dsl.py index 3fb30d8..88fc491 100644 --- a/libcxx/utils/libcxx/test/dsl.py +++ b/libcxx/utils/libcxx/test/dsl.py @@ -88,7 +88,7 @@ def _executeWithFakeConfig(test, commands): litConfig = lit.LitConfig.LitConfig( progname="lit", path=[], - quiet=False, + diagnostic_level="note", useValgrind=False, valgrindLeakCheck=False, valgrindArgs=[], diff --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py deleted file mode 100644 index 5da1d9a..0000000 --- a/libcxx/utils/libcxx/test/features.py +++ /dev/null @@ -1,920 +0,0 @@ -# ===----------------------------------------------------------------------===## -# -# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -# See https://llvm.org/LICENSE.txt for license information. -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# -# ===----------------------------------------------------------------------===## - -from libcxx.test.dsl import * -from lit.BooleanExpression import BooleanExpression -import re -import shutil -import subprocess -import sys - -_isAnyClang = lambda cfg: "__clang__" in compilerMacros(cfg) -_isAppleClang = lambda cfg: "__apple_build_version__" in compilerMacros(cfg) -_isAnyGCC = lambda cfg: "__GNUC__" in compilerMacros(cfg) -_isClang = lambda cfg: _isAnyClang(cfg) and not _isAppleClang(cfg) -_isGCC = lambda cfg: _isAnyGCC(cfg) and not _isAnyClang(cfg) -_isAnyClangOrGCC = lambda cfg: _isAnyClang(cfg) or _isAnyGCC(cfg) -_isClExe = lambda cfg: not _isAnyClangOrGCC(cfg) -_isMSVC = lambda cfg: "_MSC_VER" in compilerMacros(cfg) -_msvcVersion = lambda cfg: (int(compilerMacros(cfg)["_MSC_VER"]) // 100, int(compilerMacros(cfg)["_MSC_VER"]) % 100) - -def _getAndroidDeviceApi(cfg): - return int( - programOutput( - cfg, - r""" - #include <android/api-level.h> - #include <stdio.h> - int main(int, char**) { - printf("%d\n", android_get_device_api_level()); - return 0; - } - """, - ) - ) - - -def _mingwSupportsModules(cfg): - # Only mingw headers are known to work with libc++ built as a module, - # at the moment. - if not "__MINGW32__" in compilerMacros(cfg): - return False - # For mingw headers, check for a version known to support being built - # as a module. - return sourceBuilds( - cfg, - """ - #include <_mingw_mac.h> - #if __MINGW64_VERSION_MAJOR < 12 - #error Headers known to be incompatible - #elif __MINGW64_VERSION_MAJOR == 12 - // The headers were fixed to work with libc++ modules during - // __MINGW64_VERSION_MAJOR == 12. The headers became compatible - // with libc++ built as a module in - // 1652e9241b5d8a5a779c6582b1c3c4f4a7cc66e5 (Apr 2024), but the - // following commit 8c13b28ace68f2c0094d45121d59a4b951b533ed - // removed the now unused __mingw_static_ovr define. Use this - // as indicator for whether we've got new enough headers. - #ifdef __mingw_static_ovr - #error Headers too old - #endif - #else - // __MINGW64_VERSION_MAJOR > 12 should be ok. - #endif - int main(int, char**) { return 0; } - """, - ) - - -# Lit features are evaluated in order. Some checks may require the compiler detection to have -# run first in order to work properly. -DEFAULT_FEATURES = [ - # gcc-style-warnings detects compilers that understand -Wno-meow flags, unlike MSVC's compiler driver cl.exe. - Feature(name="gcc-style-warnings", when=_isAnyClangOrGCC), - Feature(name="cl-style-warnings", when=_isClExe), - Feature(name="apple-clang", when=_isAppleClang), - Feature( - name=lambda cfg: "apple-clang-{__clang_major__}".format(**compilerMacros(cfg)), - when=_isAppleClang, - ), - Feature( - name=lambda cfg: "apple-clang-{__clang_major__}.{__clang_minor__}".format(**compilerMacros(cfg)), - when=_isAppleClang, - ), - Feature( - name=lambda cfg: "apple-clang-{__clang_major__}.{__clang_minor__}.{__clang_patchlevel__}".format(**compilerMacros(cfg)), - when=_isAppleClang, - ), - Feature(name="clang", when=_isClang), - Feature( - name=lambda cfg: "clang-{__clang_major__}".format(**compilerMacros(cfg)), - when=_isClang, - ), - Feature( - name=lambda cfg: "clang-{__clang_major__}.{__clang_minor__}".format(**compilerMacros(cfg)), - when=_isClang, - ), - Feature( - name=lambda cfg: "clang-{__clang_major__}.{__clang_minor__}.{__clang_patchlevel__}".format(**compilerMacros(cfg)), - when=_isClang, - ), - # Note: Due to a GCC bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104760), we must disable deprecation warnings - # on GCC or spurious diagnostics are issued. - # - # TODO: - # - Enable -Wplacement-new with GCC. - # - Enable -Wclass-memaccess with GCC. - Feature( - name="gcc", - when=_isGCC, - actions=[ - AddCompileFlag("-D_LIBCPP_DISABLE_DEPRECATION_WARNINGS"), - AddCompileFlag("-Wno-placement-new"), - AddCompileFlag("-Wno-class-memaccess"), - AddFeature("GCC-ALWAYS_INLINE-FIXME"), - ], - ), - Feature( - name=lambda cfg: "gcc-{__GNUC__}".format(**compilerMacros(cfg)), when=_isGCC - ), - Feature( - name=lambda cfg: "gcc-{__GNUC__}.{__GNUC_MINOR__}".format(**compilerMacros(cfg)), - when=_isGCC, - ), - Feature( - name=lambda cfg: "gcc-{__GNUC__}.{__GNUC_MINOR__}.{__GNUC_PATCHLEVEL__}".format(**compilerMacros(cfg)), - when=_isGCC, - ), - Feature(name="msvc", when=_isMSVC), - Feature(name=lambda cfg: "msvc-{}".format(*_msvcVersion(cfg)), when=_isMSVC), - Feature(name=lambda cfg: "msvc-{}.{}".format(*_msvcVersion(cfg)), when=_isMSVC), - - Feature( - name="diagnose-if-support", - when=lambda cfg: hasCompileFlag(cfg, "-Wuser-defined-warnings"), - actions=[AddCompileFlag("-Wuser-defined-warnings")], - ), - Feature( - name="character-conversion-warnings", - when=lambda cfg: hasCompileFlag(cfg, "-Wcharacter-conversion"), - ), - # Tests to validate whether the compiler has a way to set the maximum number - # of steps during constant evaluation. Since the flag differs per compiler - # store the "valid" flag as a feature. This allows passing the proper compile - # flag to the compiler: - # // ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=12345678 - # // ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-ops-limit): -fconstexpr-ops-limit=12345678 - Feature( - name="has-fconstexpr-steps", - when=lambda cfg: hasCompileFlag(cfg, "-fconstexpr-steps=1"), - ), - Feature( - name="has-fconstexpr-ops-limit", - when=lambda cfg: hasCompileFlag(cfg, "-fconstexpr-ops-limit=1"), - ), - Feature(name="has-fblocks", when=lambda cfg: hasCompileFlag(cfg, "-fblocks")), - Feature( - name="fdelayed-template-parsing", - when=lambda cfg: hasCompileFlag(cfg, "-fdelayed-template-parsing"), - ), - Feature( - name="has-fobjc-arc", - when=lambda cfg: hasCompileFlag(cfg, "-xobjective-c++ -fobjc-arc") - and sys.platform.lower().strip() == "darwin", - ), # TODO: this doesn't handle cross-compiling to Apple platforms. - Feature( - name="objective-c++", - when=lambda cfg: hasCompileFlag(cfg, "-xobjective-c++ -fobjc-arc"), - ), - Feature( - name="verify-support", - when=lambda cfg: hasCompileFlag(cfg, "-Xclang -verify-ignore-unexpected"), - ), - Feature( - name="add-latomic-workaround", # https://llvm.org/PR73361 - when=lambda cfg: sourceBuilds( - cfg, "int main(int, char**) { return 0; }", ["-latomic"] - ), - actions=[AddLinkFlag("-latomic")], - ), - Feature( - name="has-64-bit-atomics", - when=lambda cfg: sourceBuilds( - cfg, - """ - #include <atomic> - struct Large { char storage[64/8]; }; - std::atomic<Large> x; - int main(int, char**) { (void)x.load(); (void)x.is_lock_free(); return 0; } - """, - ), - ), - Feature( - name="has-1024-bit-atomics", - when=lambda cfg: sourceBuilds( - cfg, - """ - #include <atomic> - struct Large { char storage[1024/8]; }; - std::atomic<Large> x; - int main(int, char**) { (void)x.load(); (void)x.is_lock_free(); return 0; } - """, - ), - ), - # Tests that require 64-bit architecture - Feature( - name="32-bit-pointer", - when=lambda cfg: sourceBuilds( - cfg, - """ - int main(int, char**) { - static_assert(sizeof(void *) == 4); - } - """, - ), - ), - # Check for a Windows UCRT bug (fixed in UCRT/Windows 10.0.20348.0): - # https://developercommunity.visualstudio.com/t/utf-8-locales-break-ctype-functions-for-wchar-type/1653678 - Feature( - name="win32-broken-utf8-wchar-ctype", - when=lambda cfg: not "_LIBCPP_HAS_LOCALIZATION" in compilerMacros(cfg) - or compilerMacros(cfg)["_LIBCPP_HAS_LOCALIZATION"] == "1" - and "_WIN32" in compilerMacros(cfg) - and not programSucceeds( - cfg, - """ - #include <locale.h> - #include <wctype.h> - int main(int, char**) { - setlocale(LC_ALL, "en_US.UTF-8"); - return towlower(L'\\xDA') != L'\\xFA'; - } - """, - ), - ), - # Check for a Windows UCRT bug (fixed in UCRT/Windows 10.0.19041.0). - # https://developercommunity.visualstudio.com/t/printf-formatting-with-g-outputs-too/1660837 - Feature( - name="win32-broken-printf-g-precision", - when=lambda cfg: "_WIN32" in compilerMacros(cfg) - and not programSucceeds( - cfg, - """ - #include <stdio.h> - #include <string.h> - int main(int, char**) { - char buf[100]; - snprintf(buf, sizeof(buf), "%#.*g", 0, 0.0); - return strcmp(buf, "0."); - } - """, - ), - ), - # Check for a Windows UCRT bug (not fixed upstream yet). - # With UCRT, printf("%a", 0.0) produces "0x0.0000000000000p+0", - # while other C runtimes produce just "0x0p+0". - # https://developercommunity.visualstudio.com/t/Printf-formatting-of-float-as-hex-prints/1660844 - Feature( - name="win32-broken-printf-a-precision", - when=lambda cfg: "_WIN32" in compilerMacros(cfg) - and not programSucceeds( - cfg, - """ - #include <stdio.h> - #include <string.h> - int main(int, char**) { - char buf[100]; - snprintf(buf, sizeof(buf), "%a", 0.0); - return strcmp(buf, "0x0p+0"); - } - """, - ), - ), - # Check for Glibc < 2.27, where the ru_RU.UTF-8 locale had - # mon_decimal_point == ".", which our tests don't handle. - Feature( - name="glibc-old-ru_RU-decimal-point", - when=lambda cfg: not "_LIBCPP_HAS_LOCALIZATION" in compilerMacros(cfg) - or compilerMacros(cfg)["_LIBCPP_HAS_LOCALIZATION"] == "1" - and not programSucceeds( - cfg, - """ - #include <locale.h> - #include <string.h> - int main(int, char**) { - setlocale(LC_ALL, "ru_RU.UTF-8"); - return strcmp(localeconv()->mon_decimal_point, ","); - } - """, - ), - ), - Feature( - name="has-unix-headers", - when=lambda cfg: sourceBuilds( - cfg, - """ - #include <unistd.h> - #include <sys/wait.h> - int main(int, char**) { - int fd[2]; - return pipe(fd); - } - """, - ), - ), - # Whether Bash can run on the executor. - # This is not always the case, for example when running on embedded systems. - # - # For the corner case of bash existing, but it being missing in the path - # set in %{exec} as "--env PATH=one-single-dir", the executor does find - # and executes bash, but bash then can't find any other common shell - # utilities. Test executing "bash -c 'bash --version'" to see if bash - # manages to find binaries to execute. - Feature( - name="executor-has-no-bash", - when=lambda cfg: runScriptExitCode(cfg, ["%{exec} bash -c 'bash --version'"]) != 0, - ), - # Whether module support for the platform is available. - Feature( - name="has-no-cxx-module-support", - # The libc of these platforms have functions with internal linkage. - # This is not allowed per C11 7.1.2 Standard headers/6 - # Any declaration of a library function shall have external linkage. - when=lambda cfg: "__ANDROID__" in compilerMacros(cfg) - or "__FreeBSD__" in compilerMacros(cfg) - or ("_WIN32" in compilerMacros(cfg) and not _mingwSupportsModules(cfg)) - or platform.system().lower().startswith("aix") - # Avoid building on platforms that don't support modules properly. - or not hasCompileFlag(cfg, "-Wno-reserved-module-identifier") - # older versions don't support extern "C++", newer versions don't support main in named module. - or not ( - sourceBuilds( - cfg, - """ - export module test; - extern "C++" int main(int, char**) { return 0; } - """, - ) - or sourceBuilds( - cfg, - """ - export module test; - int main(int, char**) { return 0; } - """, - ) - ), - ), - # The time zone validation tests compare the output of zdump against the - # output generated by <chrono>'s time zone support. - Feature( - name="has-no-zdump", - when=lambda cfg: runScriptExitCode(cfg, ["zdump --version"]) != 0, - ), -] - -# Deduce and add the test features that that are implied by the #defines in -# the <__config> header. -# -# For each macro of the form `_LIBCPP_XXX_YYY_ZZZ` defined below that -# is defined after including <__config>, add a Lit feature called -# `libcpp-xxx-yyy-zzz`. When a macro is defined to a specific value -# (e.g. `_LIBCPP_ABI_VERSION=2`), the feature is `libcpp-xxx-yyy-zzz=<value>`. -# -# Note that features that are more strongly tied to libc++ are named libcpp-foo, -# while features that are more general in nature are not prefixed with 'libcpp-'. -macros = { - "_LIBCPP_NO_VCRUNTIME": "libcpp-no-vcruntime", - "_LIBCPP_ABI_VERSION": "libcpp-abi-version", - "_LIBCPP_ABI_BOUNDED_ITERATORS": "libcpp-has-abi-bounded-iterators", - "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING": "libcpp-has-abi-bounded-iterators-in-string", - "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR": "libcpp-has-abi-bounded-iterators-in-vector", - "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY": "libcpp-has-abi-bounded-iterators-in-std-array", - "_LIBCPP_ABI_BOUNDED_UNIQUE_PTR": "libcpp-has-abi-bounded-unique_ptr", - "_LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE": "libcpp-has-abi-fix-unordered-container-size-type", - "_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR": "libcpp-deprecated-abi-disable-pair-trivial-copy-ctor", - "_LIBCPP_ABI_NO_COMPRESSED_PAIR_PADDING": "libcpp-abi-no-compressed-pair-padding", - "_LIBCPP_PSTL_BACKEND_LIBDISPATCH": "libcpp-pstl-backend-libdispatch", -} -for macro, feature in macros.items(): - DEFAULT_FEATURES.append( - Feature( - name=lambda cfg, m=macro, f=feature: f + ("={}".format(compilerMacros(cfg)[m]) if compilerMacros(cfg)[m] else ""), - when=lambda cfg, m=macro: m in compilerMacros(cfg), - ) - ) - -true_false_macros = { - "_LIBCPP_HAS_THREAD_API_EXTERNAL": "libcpp-has-thread-api-external", - "_LIBCPP_HAS_THREAD_API_PTHREAD": "libcpp-has-thread-api-pthread", -} -for macro, feature in true_false_macros.items(): - DEFAULT_FEATURES.append( - Feature( - name=feature, - when=lambda cfg, m=macro: m in compilerMacros(cfg) - and compilerMacros(cfg)[m] == "1", - ) - ) - -inverted_macros = { - "_LIBCPP_HAS_TIME_ZONE_DATABASE": "no-tzdb", - "_LIBCPP_HAS_FILESYSTEM": "no-filesystem", - "_LIBCPP_HAS_LOCALIZATION": "no-localization", - "_LIBCPP_HAS_THREADS": "no-threads", - "_LIBCPP_HAS_MONOTONIC_CLOCK": "no-monotonic-clock", - "_LIBCPP_HAS_WIDE_CHARACTERS": "no-wide-characters", - "_LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS": "libcpp-has-no-availability-markup", - "_LIBCPP_HAS_RANDOM_DEVICE": "no-random-device", - "_LIBCPP_HAS_UNICODE": "libcpp-has-no-unicode", - "_LIBCPP_HAS_TERMINAL": "no-terminal", -} -for macro, feature in inverted_macros.items(): - DEFAULT_FEATURES.append( - Feature( - name=feature, - when=lambda cfg, m=macro: m in compilerMacros(cfg) - and compilerMacros(cfg)[m] == "0", - ) - ) - -# Mapping from canonical locale names (used in the tests) to possible locale -# names on various systems. Each locale is considered supported if any of the -# alternative names is supported. -locales = { - "en_US.UTF-8": ["en_US.UTF-8", "en_US.utf8", "English_United States.1252"], - "fr_FR.UTF-8": ["fr_FR.UTF-8", "fr_FR.utf8", "French_France.1252"], - "ja_JP.UTF-8": ["ja_JP.UTF-8", "ja_JP.utf8", "Japanese_Japan.923"], - "ru_RU.UTF-8": ["ru_RU.UTF-8", "ru_RU.utf8", "Russian_Russia.1251"], - "zh_CN.UTF-8": ["zh_CN.UTF-8", "zh_CN.utf8", "Chinese_China.936"], - "fr_CA.ISO8859-1": ["fr_CA.ISO8859-1", "French_Canada.1252"], - "cs_CZ.ISO8859-2": ["cs_CZ.ISO8859-2", "Czech_Czech Republic.1250"], -} -provide_locale_conversions = { - "fr_FR.UTF-8": ["decimal_point", "mon_thousands_sep", "thousands_sep"], - "ru_RU.UTF-8": ["mon_thousands_sep"], -} -for locale, alts in locales.items(): - # Note: Using alts directly in the lambda body here will bind it to the value at the - # end of the loop. Assigning it to a default argument works around this issue. - DEFAULT_FEATURES.append( - Feature( - name="locale.{}".format(locale), - when=lambda cfg, alts=alts: hasAnyLocale(cfg, alts), - actions=lambda cfg, locale=locale, alts=alts: _getLocaleFlagsAction( - cfg, locale, alts, provide_locale_conversions[locale] - ) - if locale in provide_locale_conversions - and ("_LIBCPP_HAS_WIDE_CHARACTERS" not in compilerMacros(cfg) or - compilerMacros(cfg)["_LIBCPP_HAS_WIDE_CHARACTERS"] == "1") - else [], - ), - ) - - -# Provide environment locale conversions through substitutions to avoid platform specific -# maintenance. -def _getLocaleFlagsAction(cfg, locale, alts, members): - alts_list = ",".join([f'"{l}"' for l in alts]) - get_member_list = ",".join([f"lc->{m}" for m in members]) - - localeconv_info = programOutput( - cfg, - r""" - #if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS) - #define _CRT_SECURE_NO_WARNINGS - #endif - #include <stdio.h> - #include <locale.h> - #include <stdlib.h> - #include <wchar.h> - - // Print each requested locale conversion member on separate lines. - int main(int, char**) { - const char* locales[] = { %s }; - for (int loc_i = 0; loc_i < %d; ++loc_i) { - if (!setlocale(LC_ALL, locales[loc_i])) { - continue; // Choose first locale name that is recognized. - } - - lconv* lc = localeconv(); - const char* members[] = { %s }; - for (size_t m_i = 0; m_i < %d; ++m_i) { - if (!members[m_i]) { - printf("\n"); // member value is an empty string - continue; - } - - size_t len = mbstowcs(nullptr, members[m_i], 0); - if (len == static_cast<size_t>(-1)) { - fprintf(stderr, "mbstowcs failed unexpectedly\n"); - return 1; - } - // Include room for null terminator. Use malloc as these features - // are also used by lit configs that don't use -lc++ (libunwind tests). - wchar_t* dst = (wchar_t*)malloc((len + 1) * sizeof(wchar_t)); - size_t ret = mbstowcs(dst, members[m_i], len + 1); - if (ret == static_cast<size_t>(-1)) { - fprintf(stderr, "mbstowcs failed unexpectedly\n"); - free(dst); - return 1; - } - - for (size_t i = 0; i < len; ++i) { - if (dst[i] > 0x7F) { - printf("\\u%%04x", dst[i]); - } else { - // c++03 does not allow basic ascii-range characters in UCNs - printf("%%c", (char)dst[i]); - } - } - printf("\n"); - free(dst); - } - return 0; - } - - return 1; - } - """ - % (alts_list, len(alts), get_member_list, len(members)), - ) - valid_define_name = re.sub(r"[.-]", "_", locale).upper() - return [ - # Provide locale conversion through a substitution. - # Example: %{LOCALE_CONV_FR_FR_UTF_8_THOUSANDS_SEP} = L"\u202f" - AddSubstitution( - f"%{{LOCALE_CONV_{valid_define_name}_{member.upper()}}}", - lambda cfg, value=value: f"'L\"{value}\"'", - ) - for member, value in zip(members, localeconv_info.split("\n")) - ] - - -# Add features representing the target platform name: darwin, linux, windows, etc... -DEFAULT_FEATURES += [ - Feature(name="darwin", when=lambda cfg: "__APPLE__" in compilerMacros(cfg)), - Feature(name="windows", when=lambda cfg: "_WIN32" in compilerMacros(cfg)), - Feature( - name="windows-dll", - when=lambda cfg: "_WIN32" in compilerMacros(cfg) - and sourceBuilds( - cfg, - """ - #include <iostream> - int main(int, char**) { return 0; } - """, - ) - and programSucceeds( - cfg, - """ - #include <iostream> - #include <windows.h> - #include <winnt.h> - int main(int, char**) { - // Get a pointer to a data member that gets linked from the C++ - // library. This must be a data member (functions can get - // thunk inside the calling executable), and must not be - // something that is defined inline in headers. - void *ptr = &std::cout; - // Get a handle to the current main executable. - void *exe = GetModuleHandle(NULL); - // The handle points at the PE image header. Navigate through - // the header structure to find the size of the PE image (the - // executable). - PIMAGE_DOS_HEADER dosheader = (PIMAGE_DOS_HEADER)exe; - PIMAGE_NT_HEADERS ntheader = (PIMAGE_NT_HEADERS)((BYTE *)dosheader + dosheader->e_lfanew); - PIMAGE_OPTIONAL_HEADER peheader = &ntheader->OptionalHeader; - void *exeend = (BYTE*)exe + peheader->SizeOfImage; - // Check if the tested pointer - the data symbol from the - // C++ library - is located within the exe. - if (ptr >= exe && ptr <= exeend) - return 1; - // Return success if it was outside of the executable, i.e. - // loaded from a DLL. - return 0; - } - """, - ), - actions=[AddCompileFlag("-DTEST_WINDOWS_DLL")], - ), - Feature(name="linux", when=lambda cfg: "__linux__" in compilerMacros(cfg)), - Feature(name="android", when=lambda cfg: "__ANDROID__" in compilerMacros(cfg)), - Feature( - name=lambda cfg: "android-device-api={}".format(_getAndroidDeviceApi(cfg)), - when=lambda cfg: "__ANDROID__" in compilerMacros(cfg), - ), - Feature( - name="LIBCXX-ANDROID-FIXME", - when=lambda cfg: "__ANDROID__" in compilerMacros(cfg), - ), - Feature(name="netbsd", when=lambda cfg: "__NetBSD__" in compilerMacros(cfg)), - Feature(name="freebsd", when=lambda cfg: "__FreeBSD__" in compilerMacros(cfg)), - Feature( - name="LIBCXX-FREEBSD-FIXME", - when=lambda cfg: "__FreeBSD__" in compilerMacros(cfg), - ), - Feature( - name="LIBCXX-PICOLIBC-FIXME", - when=lambda cfg: sourceBuilds( - cfg, - """ - #include <string.h> - #ifndef __PICOLIBC__ - #error not picolibc - #endif - int main(int, char**) { return 0; } - """, - ), - ), - Feature( - name="LIBCXX-AMDGPU-FIXME", - when=lambda cfg: "__AMDGPU__" in compilerMacros(cfg), - ), - Feature( - name="LIBCXX-NVPTX-FIXME", - when=lambda cfg: "__NVPTX__" in compilerMacros(cfg), - ), - Feature( - name="can-create-symlinks", - when=lambda cfg: "_WIN32" not in compilerMacros(cfg) - or programSucceeds( - cfg, - # Creation of symlinks require elevated privileges on Windows unless - # Windows developer mode is enabled. - """ - #include <stdio.h> - #include <windows.h> - int main(int, char**) { - CHAR tempDirPath[MAX_PATH]; - DWORD tempPathRet = GetTempPathA(MAX_PATH, tempDirPath); - if (tempPathRet == 0 || tempPathRet > MAX_PATH) { - return 1; - } - - CHAR tempFilePath[MAX_PATH]; - UINT uRetVal = GetTempFileNameA( - tempDirPath, - "cxx", // Prefix - 0, // Unique=0 also implies file creation. - tempFilePath); - if (uRetVal == 0) { - return 1; - } - - CHAR symlinkFilePath[MAX_PATH]; - int ret = sprintf_s(symlinkFilePath, MAX_PATH, "%s_symlink", tempFilePath); - if (ret == -1) { - DeleteFileA(tempFilePath); - return 1; - } - - // Requires either administrator, or developer mode enabled. - BOOL bCreatedSymlink = CreateSymbolicLinkA(symlinkFilePath, - tempFilePath, - SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE); - if (!bCreatedSymlink) { - DeleteFileA(tempFilePath); - return 1; - } - - DeleteFileA(tempFilePath); - DeleteFileA(symlinkFilePath); - return 0; - } - """, - ), - ), -] - -# Add features representing the build host platform name. -# The build host could differ from the target platform for cross-compilation. -DEFAULT_FEATURES += [ - Feature(name="buildhost={}".format(sys.platform.lower().strip())), - # sys.platform can often be represented by a "sub-system", such as 'win32', 'cygwin', 'mingw', freebsd13 & etc. - # We define a consolidated feature on a few platforms. - Feature( - name="buildhost=windows", - when=lambda cfg: platform.system().lower().startswith("windows"), - ), - Feature( - name="buildhost=freebsd", - when=lambda cfg: platform.system().lower().startswith("freebsd"), - ), - Feature( - name="buildhost=aix", - when=lambda cfg: platform.system().lower().startswith("aix"), - ), -] - -# Detect whether GDB is on the system, has Python scripting and supports -# adding breakpoint commands. If so add a substitution to access it. -def check_gdb(cfg): - gdb_path = shutil.which("gdb") - if gdb_path is None: - return False - - # Check that we can set breakpoint commands, which was added in 8.3. - # Using the quit command here means that gdb itself exits, not just - # the "python <...>" command. - test_src = """\ -try: - gdb.Breakpoint(\"main\").commands=\"foo\" -except AttributeError: - gdb.execute(\"quit 1\") -gdb.execute(\"quit\")""" - - try: - stdout = subprocess.check_output( - [gdb_path, "-ex", "python " + test_src, "--batch"], - stderr=subprocess.DEVNULL, - universal_newlines=True, - ) - except subprocess.CalledProcessError: - # We can't set breakpoint commands - return False - - # Check we actually ran the Python - return not "Python scripting is not supported" in stdout - - -DEFAULT_FEATURES += [ - Feature( - name="host-has-gdb-with-python", - when=check_gdb, - actions=[AddSubstitution("%{gdb}", lambda cfg: shutil.which("gdb"))], - ) -] - -# Helpers to define correspondances between LLVM versions and vendor system versions. -# Those are used for backdeployment features below, do not use directly in tests. -DEFAULT_FEATURES += [ - Feature( - name="_target-has-llvm-22", - when=lambda cfg: BooleanExpression.evaluate( - "TBD", - cfg.available_features, - ), - ), - Feature( - name="_target-has-llvm-21", - when=lambda cfg: BooleanExpression.evaluate( - "TBD", - cfg.available_features, - ), - ), - Feature( - name="_target-has-llvm-20", - when=lambda cfg: BooleanExpression.evaluate( - "_target-has-llvm-21 || target={{.+}}-apple-macosx{{26.[0-9](.\d+)?}}", - cfg.available_features, - ), - ), - Feature( - name="_target-has-llvm-19", - when=lambda cfg: BooleanExpression.evaluate( - "_target-has-llvm-20 || target={{.+}}-apple-macosx{{15.[4-9](.\d+)?}}", - cfg.available_features, - ), - ), - Feature( - name="_target-has-llvm-18", - when=lambda cfg: BooleanExpression.evaluate( - "_target-has-llvm-19 || target={{.+}}-apple-macosx{{15.[0-3](.\d+)?}}", - cfg.available_features, - ), - ), - Feature( - name="_target-has-llvm-17", - when=lambda cfg: BooleanExpression.evaluate( - "_target-has-llvm-18 || target={{.+}}-apple-macosx{{14.[4-9](.\d+)?}}", - cfg.available_features, - ), - ), - Feature( - name="_target-has-llvm-16", - when=lambda cfg: BooleanExpression.evaluate( - "_target-has-llvm-17 || target={{.+}}-apple-macosx{{14.[0-3](.[0-9]+)?}}", - cfg.available_features, - ), - ), - Feature( - name="_target-has-llvm-15", - when=lambda cfg: BooleanExpression.evaluate( - "_target-has-llvm-16 || target={{.+}}-apple-macosx{{13.[4-9](.[0-9]+)?}}", - cfg.available_features, - ), - ), - Feature( - name="_target-has-llvm-14", - when=lambda cfg: BooleanExpression.evaluate( - "_target-has-llvm-15", - cfg.available_features, - ), - ), - Feature( - name="_target-has-llvm-13", - when=lambda cfg: BooleanExpression.evaluate( - "_target-has-llvm-14 || target={{.+}}-apple-macosx{{13.[0-3](.[0-9]+)?}}", - cfg.available_features, - ), - ), - Feature( - name="_target-has-llvm-12", - when=lambda cfg: BooleanExpression.evaluate( - "_target-has-llvm-13 || target={{.+}}-apple-macosx{{12.[3-9](.[0-9]+)?}}", - cfg.available_features, - ), - ), -] - -# Define features for back-deployment testing. -# -# These features can be used to XFAIL tests that fail when deployed on (or compiled -# for) an older system. For example, if a test exhibits a bug in the libc++ on a -# particular system version, or if it uses a symbol that is not available on an -# older version of the dylib, it can be marked as XFAIL with these features. -# -# We have two families of Lit features: -# -# The first one is `using-built-library-before-llvm-XYZ`. These features encode the -# fact that the test suite is being *run* against a version of the shared/static library -# that predates LLVM version XYZ. This is useful to represent the use case of compiling -# a program against the latest libc++ but then deploying it and running it on an older -# system with an older version of the (usually shared) library. -# -# This feature is built up using the target triple passed to the compiler and the -# `stdlib=system` Lit feature, which encodes that we're running against the same library -# as described by the target triple. -# -# The second set of features is `availability-<FEATURE>-missing`. This family of Lit -# features encodes the presence of availability markup in the libc++ headers. This is -# useful to check that a test fails specifically when compiled for a given deployment -# target, such as when testing availability markup where we want to make sure that -# using the annotated facility on a deployment target that doesn't support it will fail -# at compile time. This can be achieved by creating a `.verify.cpp` test that checks for -# the right errors and marking the test as `REQUIRES: availability-<FEATURE>-missing`. -# -# This feature is built up using the presence of availability markup detected inside -# __config, the flavor of the library being tested and the target triple passed to the -# compiler. -# -# Note that both families of Lit features are similar but different in important ways. -# For example, tests for availability markup should be expected to produce diagnostics -# regardless of whether we're running against a system library, as long as we're using -# a libc++ flavor that enables availability markup. Similarly, a test could fail when -# run against the system library of an older version of FreeBSD, even though FreeBSD -# doesn't provide availability markup at the time of writing this. -for version in ("12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22"): - DEFAULT_FEATURES.append( - Feature( - name="using-built-library-before-llvm-{}".format(version), - when=lambda cfg, v=version: BooleanExpression.evaluate( - "stdlib=system && !_target-has-llvm-{}".format(v), - cfg.available_features, - ), - ) - ) - -DEFAULT_FEATURES += [ - # Tests that require https://wg21.link/P0482 support in the built library - Feature( - name="availability-char8_t_support-missing", - when=lambda cfg: BooleanExpression.evaluate( - "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-12)", - cfg.available_features, - ), - ), - # Tests that require std::to_chars(floating-point) in the built library - Feature( - name="availability-fp_to_chars-missing", - when=lambda cfg: BooleanExpression.evaluate( - "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-14)", - cfg.available_features, - ), - ), - # Tests that require __libcpp_verbose_abort support in the built library - Feature( - name="availability-verbose_abort-missing", - when=lambda cfg: BooleanExpression.evaluate( - "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-15)", - cfg.available_features, - ), - ), - # Tests that require std::pmr support in the built library - Feature( - name="availability-pmr-missing", - when=lambda cfg: BooleanExpression.evaluate( - "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-16)", - cfg.available_features, - ), - ), - # Tests that require support for <print> and std::print in <ostream> in the built library. - Feature( - name="availability-print-missing", - when=lambda cfg: BooleanExpression.evaluate( - "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-18)", - cfg.available_features, - ), - ), - # Tests that require time zone database support in the built library - Feature( - name="availability-tzdb-missing", - when=lambda cfg: BooleanExpression.evaluate( - "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-19)", - cfg.available_features, - ), - ), - # Tests that require std::from_chars(floating-point) in the built library - Feature( - name="availability-fp_from_chars-missing", - when=lambda cfg: BooleanExpression.evaluate( - "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-20)", - cfg.available_features, - ), - ), -] diff --git a/libcxx/utils/libcxx/test/features/__init__.py b/libcxx/utils/libcxx/test/features/__init__.py new file mode 100644 index 0000000..5c0d1f3 --- /dev/null +++ b/libcxx/utils/libcxx/test/features/__init__.py @@ -0,0 +1,21 @@ +# ===----------------------------------------------------------------------===## +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# ===----------------------------------------------------------------------===## + +from . import availability, compiler, gdb, libcxx_macros, localization, misc, platform + +# Lit features are evaluated in order. Some features depend on other features, so +# we are careful to define them in the correct order. For example, several features +# require the compiler detection to have been performed. +DEFAULT_FEATURES = [] +DEFAULT_FEATURES += compiler.features +DEFAULT_FEATURES += libcxx_macros.features +DEFAULT_FEATURES += platform.features +DEFAULT_FEATURES += localization.features +DEFAULT_FEATURES += gdb.features +DEFAULT_FEATURES += misc.features +DEFAULT_FEATURES += availability.features diff --git a/libcxx/utils/libcxx/test/features/availability.py b/libcxx/utils/libcxx/test/features/availability.py new file mode 100644 index 0000000..39c6cf4 --- /dev/null +++ b/libcxx/utils/libcxx/test/features/availability.py @@ -0,0 +1,199 @@ +# ===----------------------------------------------------------------------===## +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# ===----------------------------------------------------------------------===## + +from libcxx.test.dsl import Feature +from lit.BooleanExpression import BooleanExpression + +# Helpers to define correspondances between LLVM versions and vendor system versions. +# Those are used for backdeployment features below, do not use directly in tests. +features = [ + Feature( + name="_target-has-llvm-22", + when=lambda cfg: BooleanExpression.evaluate( + "TBD", + cfg.available_features, + ), + ), + Feature( + name="_target-has-llvm-21", + when=lambda cfg: BooleanExpression.evaluate( + "TBD", + cfg.available_features, + ), + ), + Feature( + name="_target-has-llvm-20", + when=lambda cfg: BooleanExpression.evaluate( + r"_target-has-llvm-21 || target={{.+}}-apple-macosx{{26.[0-9](.\d+)?}}", + cfg.available_features, + ), + ), + Feature( + name="_target-has-llvm-19", + when=lambda cfg: BooleanExpression.evaluate( + r"_target-has-llvm-20 || target={{.+}}-apple-macosx{{15.[4-9](.\d+)?}}", + cfg.available_features, + ), + ), + Feature( + name="_target-has-llvm-18", + when=lambda cfg: BooleanExpression.evaluate( + r"_target-has-llvm-19 || target={{.+}}-apple-macosx{{15.[0-3](.\d+)?}}", + cfg.available_features, + ), + ), + Feature( + name="_target-has-llvm-17", + when=lambda cfg: BooleanExpression.evaluate( + r"_target-has-llvm-18 || target={{.+}}-apple-macosx{{14.[4-9](.\d+)?}}", + cfg.available_features, + ), + ), + Feature( + name="_target-has-llvm-16", + when=lambda cfg: BooleanExpression.evaluate( + "_target-has-llvm-17 || target={{.+}}-apple-macosx{{14.[0-3](.[0-9]+)?}}", + cfg.available_features, + ), + ), + Feature( + name="_target-has-llvm-15", + when=lambda cfg: BooleanExpression.evaluate( + "_target-has-llvm-16 || target={{.+}}-apple-macosx{{13.[4-9](.[0-9]+)?}}", + cfg.available_features, + ), + ), + Feature( + name="_target-has-llvm-14", + when=lambda cfg: BooleanExpression.evaluate( + "_target-has-llvm-15", + cfg.available_features, + ), + ), + Feature( + name="_target-has-llvm-13", + when=lambda cfg: BooleanExpression.evaluate( + "_target-has-llvm-14 || target={{.+}}-apple-macosx{{13.[0-3](.[0-9]+)?}}", + cfg.available_features, + ), + ), + Feature( + name="_target-has-llvm-12", + when=lambda cfg: BooleanExpression.evaluate( + "_target-has-llvm-13 || target={{.+}}-apple-macosx{{12.[3-9](.[0-9]+)?}}", + cfg.available_features, + ), + ), +] + +# Define features for back-deployment testing. +# +# These features can be used to XFAIL tests that fail when deployed on (or compiled +# for) an older system. For example, if a test exhibits a bug in the libc++ on a +# particular system version, or if it uses a symbol that is not available on an +# older version of the dylib, it can be marked as XFAIL with these features. +# +# We have two families of Lit features: +# +# The first one is `using-built-library-before-llvm-XYZ`. These features encode the +# fact that the test suite is being *run* against a version of the shared/static library +# that predates LLVM version XYZ. This is useful to represent the use case of compiling +# a program against the latest libc++ but then deploying it and running it on an older +# system with an older version of the (usually shared) library. +# +# This feature is built up using the target triple passed to the compiler and the +# `stdlib=system` Lit feature, which encodes that we're running against the same library +# as described by the target triple. +# +# The second set of features is `availability-<FEATURE>-missing`. This family of Lit +# features encodes the presence of availability markup in the libc++ headers. This is +# useful to check that a test fails specifically when compiled for a given deployment +# target, such as when testing availability markup where we want to make sure that +# using the annotated facility on a deployment target that doesn't support it will fail +# at compile time. This can be achieved by creating a `.verify.cpp` test that checks for +# the right errors and marking the test as `REQUIRES: availability-<FEATURE>-missing`. +# +# This feature is built up using the presence of availability markup detected inside +# __config, the flavor of the library being tested and the target triple passed to the +# compiler. +# +# Note that both families of Lit features are similar but different in important ways. +# For example, tests for availability markup should be expected to produce diagnostics +# regardless of whether we're running against a system library, as long as we're using +# a libc++ flavor that enables availability markup. Similarly, a test could fail when +# run against the system library of an older version of FreeBSD, even though FreeBSD +# doesn't provide availability markup at the time of writing this. +for version in ("12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22"): + features.append( + Feature( + name="using-built-library-before-llvm-{}".format(version), + when=lambda cfg, v=version: BooleanExpression.evaluate( + "stdlib=system && !_target-has-llvm-{}".format(v), + cfg.available_features, + ), + ) + ) + +features += [ + # Tests that require https://wg21.link/P0482 support in the built library + Feature( + name="availability-char8_t_support-missing", + when=lambda cfg: BooleanExpression.evaluate( + "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-12)", + cfg.available_features, + ), + ), + # Tests that require std::to_chars(floating-point) in the built library + Feature( + name="availability-fp_to_chars-missing", + when=lambda cfg: BooleanExpression.evaluate( + "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-14)", + cfg.available_features, + ), + ), + # Tests that require __libcpp_verbose_abort support in the built library + Feature( + name="availability-verbose_abort-missing", + when=lambda cfg: BooleanExpression.evaluate( + "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-15)", + cfg.available_features, + ), + ), + # Tests that require std::pmr support in the built library + Feature( + name="availability-pmr-missing", + when=lambda cfg: BooleanExpression.evaluate( + "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-16)", + cfg.available_features, + ), + ), + # Tests that require support for <print> and std::print in <ostream> in the built library. + Feature( + name="availability-print-missing", + when=lambda cfg: BooleanExpression.evaluate( + "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-18)", + cfg.available_features, + ), + ), + # Tests that require time zone database support in the built library + Feature( + name="availability-tzdb-missing", + when=lambda cfg: BooleanExpression.evaluate( + "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-19)", + cfg.available_features, + ), + ), + # Tests that require std::from_chars(floating-point) in the built library + Feature( + name="availability-fp_from_chars-missing", + when=lambda cfg: BooleanExpression.evaluate( + "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-20)", + cfg.available_features, + ), + ), +] diff --git a/libcxx/utils/libcxx/test/features/compiler.py b/libcxx/utils/libcxx/test/features/compiler.py new file mode 100644 index 0000000..2fb2d4b --- /dev/null +++ b/libcxx/utils/libcxx/test/features/compiler.py @@ -0,0 +1,82 @@ +# ===----------------------------------------------------------------------===## +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# ===----------------------------------------------------------------------===## + +from libcxx.test.dsl import compilerMacros, Feature, AddCompileFlag, AddFeature + +_isAnyClang = lambda cfg: "__clang__" in compilerMacros(cfg) +_isAppleClang = lambda cfg: "__apple_build_version__" in compilerMacros(cfg) +_isAnyGCC = lambda cfg: "__GNUC__" in compilerMacros(cfg) +_isClang = lambda cfg: _isAnyClang(cfg) and not _isAppleClang(cfg) +_isGCC = lambda cfg: _isAnyGCC(cfg) and not _isAnyClang(cfg) +_isAnyClangOrGCC = lambda cfg: _isAnyClang(cfg) or _isAnyGCC(cfg) +_isClExe = lambda cfg: not _isAnyClangOrGCC(cfg) +_isMSVC = lambda cfg: "_MSC_VER" in compilerMacros(cfg) +_msvcVersion = lambda cfg: (int(compilerMacros(cfg)["_MSC_VER"]) // 100, int(compilerMacros(cfg)["_MSC_VER"]) % 100) + +features = [ + # gcc-style-warnings detects compilers that understand -Wno-meow flags, unlike MSVC's compiler driver cl.exe. + Feature(name="gcc-style-warnings", when=_isAnyClangOrGCC), + Feature(name="cl-style-warnings", when=_isClExe), + + Feature(name="apple-clang", when=_isAppleClang), + Feature( + name=lambda cfg: "apple-clang-{__clang_major__}".format(**compilerMacros(cfg)), + when=_isAppleClang, + ), + Feature( + name=lambda cfg: "apple-clang-{__clang_major__}.{__clang_minor__}".format(**compilerMacros(cfg)), + when=_isAppleClang, + ), + Feature( + name=lambda cfg: "apple-clang-{__clang_major__}.{__clang_minor__}.{__clang_patchlevel__}".format(**compilerMacros(cfg)), + when=_isAppleClang, + ), + Feature(name="clang", when=_isClang), + Feature( + name=lambda cfg: "clang-{__clang_major__}".format(**compilerMacros(cfg)), + when=_isClang, + ), + Feature( + name=lambda cfg: "clang-{__clang_major__}.{__clang_minor__}".format(**compilerMacros(cfg)), + when=_isClang, + ), + Feature( + name=lambda cfg: "clang-{__clang_major__}.{__clang_minor__}.{__clang_patchlevel__}".format(**compilerMacros(cfg)), + when=_isClang, + ), + # Note: Due to a GCC bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104760), we must disable deprecation warnings + # on GCC or spurious diagnostics are issued. + # + # TODO: + # - Enable -Wplacement-new with GCC. + # - Enable -Wclass-memaccess with GCC. + Feature( + name="gcc", + when=_isGCC, + actions=[ + AddCompileFlag("-D_LIBCPP_DISABLE_DEPRECATION_WARNINGS"), + AddCompileFlag("-Wno-placement-new"), + AddCompileFlag("-Wno-class-memaccess"), + AddFeature("GCC-ALWAYS_INLINE-FIXME"), + ], + ), + Feature( + name=lambda cfg: "gcc-{__GNUC__}".format(**compilerMacros(cfg)), when=_isGCC + ), + Feature( + name=lambda cfg: "gcc-{__GNUC__}.{__GNUC_MINOR__}".format(**compilerMacros(cfg)), + when=_isGCC, + ), + Feature( + name=lambda cfg: "gcc-{__GNUC__}.{__GNUC_MINOR__}.{__GNUC_PATCHLEVEL__}".format(**compilerMacros(cfg)), + when=_isGCC, + ), + Feature(name="msvc", when=_isMSVC), + Feature(name=lambda cfg: "msvc-{}".format(*_msvcVersion(cfg)), when=_isMSVC), + Feature(name=lambda cfg: "msvc-{}.{}".format(*_msvcVersion(cfg)), when=_isMSVC), +] diff --git a/libcxx/utils/libcxx/test/features/gdb.py b/libcxx/utils/libcxx/test/features/gdb.py new file mode 100644 index 0000000..459a59a --- /dev/null +++ b/libcxx/utils/libcxx/test/features/gdb.py @@ -0,0 +1,50 @@ +# ===----------------------------------------------------------------------===## +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# ===----------------------------------------------------------------------===## + +from libcxx.test.dsl import Feature, AddSubstitution +import shutil +import subprocess + +# Detect whether GDB is on the system, has Python scripting and supports +# adding breakpoint commands. If so add a substitution to access it. +def check_gdb(cfg): + gdb_path = shutil.which("gdb") + if gdb_path is None: + return False + + # Check that we can set breakpoint commands, which was added in 8.3. + # Using the quit command here means that gdb itself exits, not just + # the "python <...>" command. + test_src = """\ +try: + gdb.Breakpoint(\"main\").commands=\"foo\" +except AttributeError: + gdb.execute(\"quit 1\") +gdb.execute(\"quit\")""" + + try: + stdout = subprocess.check_output( + [gdb_path, "-ex", "python " + test_src, "--batch"], + stderr=subprocess.DEVNULL, + universal_newlines=True, + ) + except subprocess.CalledProcessError: + # We can't set breakpoint commands + return False + + # Check we actually ran the Python + return not "Python scripting is not supported" in stdout + + +features = [ + Feature( + name="host-has-gdb-with-python", + when=check_gdb, + actions=[AddSubstitution("%{gdb}", lambda cfg: shutil.which("gdb"))], + ) +] diff --git a/libcxx/utils/libcxx/test/features/libcxx_macros.py b/libcxx/utils/libcxx/test/features/libcxx_macros.py new file mode 100644 index 0000000..7a465f2 --- /dev/null +++ b/libcxx/utils/libcxx/test/features/libcxx_macros.py @@ -0,0 +1,76 @@ +# ===----------------------------------------------------------------------===## +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# ===----------------------------------------------------------------------===## + +from libcxx.test.dsl import Feature, compilerMacros + +features = [] + +# Deduce and add the test features that that are implied by the #defines in +# the <__config> header. +# +# For each macro of the form `_LIBCPP_XXX_YYY_ZZZ` defined below that +# is defined after including <__config>, add a Lit feature called +# `libcpp-xxx-yyy-zzz`. When a macro is defined to a specific value +# (e.g. `_LIBCPP_ABI_VERSION=2`), the feature is `libcpp-xxx-yyy-zzz=<value>`. +# +# Note that features that are more strongly tied to libc++ are named libcpp-foo, +# while features that are more general in nature are not prefixed with 'libcpp-'. +macros = { + "_LIBCPP_NO_VCRUNTIME": "libcpp-no-vcruntime", + "_LIBCPP_ABI_VERSION": "libcpp-abi-version", + "_LIBCPP_ABI_BOUNDED_ITERATORS": "libcpp-has-abi-bounded-iterators", + "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING": "libcpp-has-abi-bounded-iterators-in-string", + "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR": "libcpp-has-abi-bounded-iterators-in-vector", + "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY": "libcpp-has-abi-bounded-iterators-in-std-array", + "_LIBCPP_ABI_BOUNDED_UNIQUE_PTR": "libcpp-has-abi-bounded-unique_ptr", + "_LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE": "libcpp-has-abi-fix-unordered-container-size-type", + "_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR": "libcpp-deprecated-abi-disable-pair-trivial-copy-ctor", + "_LIBCPP_ABI_NO_COMPRESSED_PAIR_PADDING": "libcpp-abi-no-compressed-pair-padding", + "_LIBCPP_PSTL_BACKEND_LIBDISPATCH": "libcpp-pstl-backend-libdispatch", +} +for macro, feature in macros.items(): + features.append( + Feature( + name=lambda cfg, m=macro, f=feature: f + ("={}".format(compilerMacros(cfg)[m]) if compilerMacros(cfg)[m] else ""), + when=lambda cfg, m=macro: m in compilerMacros(cfg), + ) + ) + +true_false_macros = { + "_LIBCPP_HAS_THREAD_API_EXTERNAL": "libcpp-has-thread-api-external", + "_LIBCPP_HAS_THREAD_API_PTHREAD": "libcpp-has-thread-api-pthread", +} +for macro, feature in true_false_macros.items(): + features.append( + Feature( + name=feature, + when=lambda cfg, m=macro: m in compilerMacros(cfg) + and compilerMacros(cfg)[m] == "1", + ) + ) + +inverted_macros = { + "_LIBCPP_HAS_TIME_ZONE_DATABASE": "no-tzdb", + "_LIBCPP_HAS_FILESYSTEM": "no-filesystem", + "_LIBCPP_HAS_LOCALIZATION": "no-localization", + "_LIBCPP_HAS_THREADS": "no-threads", + "_LIBCPP_HAS_MONOTONIC_CLOCK": "no-monotonic-clock", + "_LIBCPP_HAS_WIDE_CHARACTERS": "no-wide-characters", + "_LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS": "libcpp-has-no-availability-markup", + "_LIBCPP_HAS_RANDOM_DEVICE": "no-random-device", + "_LIBCPP_HAS_UNICODE": "libcpp-has-no-unicode", + "_LIBCPP_HAS_TERMINAL": "no-terminal", +} +for macro, feature in inverted_macros.items(): + features.append( + Feature( + name=feature, + when=lambda cfg, m=macro: m in compilerMacros(cfg) + and compilerMacros(cfg)[m] == "0", + ) + ) diff --git a/libcxx/utils/libcxx/test/features/localization.py b/libcxx/utils/libcxx/test/features/localization.py new file mode 100644 index 0000000..157c250 --- /dev/null +++ b/libcxx/utils/libcxx/test/features/localization.py @@ -0,0 +1,142 @@ +# ===----------------------------------------------------------------------===## +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# ===----------------------------------------------------------------------===## + +from libcxx.test.dsl import compilerMacros, Feature, programSucceeds, hasAnyLocale, programOutput, AddSubstitution +import re + +features = [ + # Check for Glibc < 2.27, where the ru_RU.UTF-8 locale had + # mon_decimal_point == ".", which our tests don't handle. + Feature( + name="glibc-old-ru_RU-decimal-point", + when=lambda cfg: not "_LIBCPP_HAS_LOCALIZATION" in compilerMacros(cfg) + or compilerMacros(cfg)["_LIBCPP_HAS_LOCALIZATION"] == "1" + and not programSucceeds( + cfg, + """ + #include <locale.h> + #include <string.h> + int main(int, char**) { + setlocale(LC_ALL, "ru_RU.UTF-8"); + return strcmp(localeconv()->mon_decimal_point, ","); + } + """, + ), + ), +] + +# Mapping from canonical locale names (used in the tests) to possible locale +# names on various systems. Each locale is considered supported if any of the +# alternative names is supported. +_locales = { + "en_US.UTF-8": ["en_US.UTF-8", "en_US.utf8", "English_United States.1252"], + "fr_FR.UTF-8": ["fr_FR.UTF-8", "fr_FR.utf8", "French_France.1252"], + "ja_JP.UTF-8": ["ja_JP.UTF-8", "ja_JP.utf8", "Japanese_Japan.923"], + "ru_RU.UTF-8": ["ru_RU.UTF-8", "ru_RU.utf8", "Russian_Russia.1251"], + "zh_CN.UTF-8": ["zh_CN.UTF-8", "zh_CN.utf8", "Chinese_China.936"], + "fr_CA.ISO8859-1": ["fr_CA.ISO8859-1", "French_Canada.1252"], + "cs_CZ.ISO8859-2": ["cs_CZ.ISO8859-2", "Czech_Czech Republic.1250"], +} +_provide_locale_conversions = { + "fr_FR.UTF-8": ["decimal_point", "mon_thousands_sep", "thousands_sep"], + "ru_RU.UTF-8": ["mon_thousands_sep"], +} +for locale, alts in _locales.items(): + # Note: Using alts directly in the lambda body here will bind it to the value at the + # end of the loop. Assigning it to a default argument works around this issue. + features.append( + Feature( + name="locale.{}".format(locale), + when=lambda cfg, alts=alts: hasAnyLocale(cfg, alts), + actions=lambda cfg, locale=locale, alts=alts: _getLocaleFlagsAction( + cfg, locale, alts, _provide_locale_conversions[locale] + ) + if locale in _provide_locale_conversions + and ("_LIBCPP_HAS_WIDE_CHARACTERS" not in compilerMacros(cfg) or + compilerMacros(cfg)["_LIBCPP_HAS_WIDE_CHARACTERS"] == "1") + else [], + ), + ) + +# Provide environment locale conversions through substitutions to avoid platform specific +# maintenance. +def _getLocaleFlagsAction(cfg, locale, alts, members): + alts_list = ",".join([f'"{l}"' for l in alts]) + get_member_list = ",".join([f"lc->{m}" for m in members]) + + localeconv_info = programOutput( + cfg, + r""" + #if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS) + #define _CRT_SECURE_NO_WARNINGS + #endif + #include <stdio.h> + #include <locale.h> + #include <stdlib.h> + #include <wchar.h> + + // Print each requested locale conversion member on separate lines. + int main(int, char**) { + const char* locales[] = { %s }; + for (int loc_i = 0; loc_i < %d; ++loc_i) { + if (!setlocale(LC_ALL, locales[loc_i])) { + continue; // Choose first locale name that is recognized. + } + + lconv* lc = localeconv(); + const char* members[] = { %s }; + for (size_t m_i = 0; m_i < %d; ++m_i) { + if (!members[m_i]) { + printf("\n"); // member value is an empty string + continue; + } + + size_t len = mbstowcs(nullptr, members[m_i], 0); + if (len == static_cast<size_t>(-1)) { + fprintf(stderr, "mbstowcs failed unexpectedly\n"); + return 1; + } + // Include room for null terminator. Use malloc as these features + // are also used by lit configs that don't use -lc++ (libunwind tests). + wchar_t* dst = (wchar_t*)malloc((len + 1) * sizeof(wchar_t)); + size_t ret = mbstowcs(dst, members[m_i], len + 1); + if (ret == static_cast<size_t>(-1)) { + fprintf(stderr, "mbstowcs failed unexpectedly\n"); + free(dst); + return 1; + } + + for (size_t i = 0; i < len; ++i) { + if (dst[i] > 0x7F) { + printf("\\u%%04x", dst[i]); + } else { + // c++03 does not allow basic ascii-range characters in UCNs + printf("%%c", (char)dst[i]); + } + } + printf("\n"); + free(dst); + } + return 0; + } + + return 1; + } + """ + % (alts_list, len(alts), get_member_list, len(members)), + ) + valid_define_name = re.sub(r"[.-]", "_", locale).upper() + return [ + # Provide locale conversion through a substitution. + # Example: %{LOCALE_CONV_FR_FR_UTF_8_THOUSANDS_SEP} = L"\u202f" + AddSubstitution( + f"%{{LOCALE_CONV_{valid_define_name}_{member.upper()}}}", + lambda cfg, value=value: f"'L\"{value}\"'", + ) + for member, value in zip(members, localeconv_info.split("\n")) + ] diff --git a/libcxx/utils/libcxx/test/features/misc.py b/libcxx/utils/libcxx/test/features/misc.py new file mode 100644 index 0000000..738e3d8 --- /dev/null +++ b/libcxx/utils/libcxx/test/features/misc.py @@ -0,0 +1,299 @@ +# ===----------------------------------------------------------------------===## +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# ===----------------------------------------------------------------------===## + +from libcxx.test.dsl import compilerMacros, sourceBuilds, hasCompileFlag, programSucceeds, runScriptExitCode +from libcxx.test.dsl import Feature, AddCompileFlag, AddLinkFlag +import platform +import sys + +def _mingwSupportsModules(cfg): + # Only mingw headers are known to work with libc++ built as a module, + # at the moment. + if not "__MINGW32__" in compilerMacros(cfg): + return False + # For mingw headers, check for a version known to support being built + # as a module. + return sourceBuilds( + cfg, + """ + #include <_mingw_mac.h> + #if __MINGW64_VERSION_MAJOR < 12 + #error Headers known to be incompatible + #elif __MINGW64_VERSION_MAJOR == 12 + // The headers were fixed to work with libc++ modules during + // __MINGW64_VERSION_MAJOR == 12. The headers became compatible + // with libc++ built as a module in + // 1652e9241b5d8a5a779c6582b1c3c4f4a7cc66e5 (Apr 2024), but the + // following commit 8c13b28ace68f2c0094d45121d59a4b951b533ed + // removed the now unused __mingw_static_ovr define. Use this + // as indicator for whether we've got new enough headers. + #ifdef __mingw_static_ovr + #error Headers too old + #endif + #else + // __MINGW64_VERSION_MAJOR > 12 should be ok. + #endif + int main(int, char**) { return 0; } + """, + ) + +features = [ + Feature( + name="diagnose-if-support", + when=lambda cfg: hasCompileFlag(cfg, "-Wuser-defined-warnings"), + actions=[AddCompileFlag("-Wuser-defined-warnings")], + ), + Feature( + name="character-conversion-warnings", + when=lambda cfg: hasCompileFlag(cfg, "-Wcharacter-conversion"), + ), + # Tests to validate whether the compiler has a way to set the maximum number + # of steps during constant evaluation. Since the flag differs per compiler + # store the "valid" flag as a feature. This allows passing the proper compile + # flag to the compiler: + # // ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=12345678 + # // ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-ops-limit): -fconstexpr-ops-limit=12345678 + Feature( + name="has-fconstexpr-steps", + when=lambda cfg: hasCompileFlag(cfg, "-fconstexpr-steps=1"), + ), + Feature( + name="has-fconstexpr-ops-limit", + when=lambda cfg: hasCompileFlag(cfg, "-fconstexpr-ops-limit=1"), + ), + Feature(name="has-fblocks", when=lambda cfg: hasCompileFlag(cfg, "-fblocks")), + Feature( + name="fdelayed-template-parsing", + when=lambda cfg: hasCompileFlag(cfg, "-fdelayed-template-parsing"), + ), + Feature( + name="has-fobjc-arc", + when=lambda cfg: hasCompileFlag(cfg, "-xobjective-c++ -fobjc-arc") + and sys.platform.lower().strip() == "darwin", + ), # TODO: this doesn't handle cross-compiling to Apple platforms. + Feature( + name="objective-c++", + when=lambda cfg: hasCompileFlag(cfg, "-xobjective-c++ -fobjc-arc"), + ), + Feature( + name="verify-support", + when=lambda cfg: hasCompileFlag(cfg, "-Xclang -verify-ignore-unexpected"), + ), + Feature( + name="add-latomic-workaround", # https://llvm.org/PR73361 + when=lambda cfg: sourceBuilds( + cfg, "int main(int, char**) { return 0; }", ["-latomic"] + ), + actions=[AddLinkFlag("-latomic")], + ), + Feature( + name="has-64-bit-atomics", + when=lambda cfg: sourceBuilds( + cfg, + """ + #include <atomic> + struct Large { char storage[64/8]; }; + std::atomic<Large> x; + int main(int, char**) { (void)x.load(); (void)x.is_lock_free(); return 0; } + """, + ), + ), + Feature( + name="has-1024-bit-atomics", + when=lambda cfg: sourceBuilds( + cfg, + """ + #include <atomic> + struct Large { char storage[1024/8]; }; + std::atomic<Large> x; + int main(int, char**) { (void)x.load(); (void)x.is_lock_free(); return 0; } + """, + ), + ), + # Tests that require 64-bit architecture + Feature( + name="32-bit-pointer", + when=lambda cfg: sourceBuilds( + cfg, + """ + int main(int, char**) { + static_assert(sizeof(void *) == 4); + } + """, + ), + ), + # Check for a Windows UCRT bug (fixed in UCRT/Windows 10.0.20348.0): + # https://developercommunity.visualstudio.com/t/utf-8-locales-break-ctype-functions-for-wchar-type/1653678 + Feature( + name="win32-broken-utf8-wchar-ctype", + when=lambda cfg: not "_LIBCPP_HAS_LOCALIZATION" in compilerMacros(cfg) + or compilerMacros(cfg)["_LIBCPP_HAS_LOCALIZATION"] == "1" + and "_WIN32" in compilerMacros(cfg) + and not programSucceeds( + cfg, + """ + #include <locale.h> + #include <wctype.h> + int main(int, char**) { + setlocale(LC_ALL, "en_US.UTF-8"); + return towlower(L'\\xDA') != L'\\xFA'; + } + """, + ), + ), + # Check for a Windows UCRT bug (fixed in UCRT/Windows 10.0.19041.0). + # https://developercommunity.visualstudio.com/t/printf-formatting-with-g-outputs-too/1660837 + Feature( + name="win32-broken-printf-g-precision", + when=lambda cfg: "_WIN32" in compilerMacros(cfg) + and not programSucceeds( + cfg, + """ + #include <stdio.h> + #include <string.h> + int main(int, char**) { + char buf[100]; + snprintf(buf, sizeof(buf), "%#.*g", 0, 0.0); + return strcmp(buf, "0."); + } + """, + ), + ), + # Check for a Windows UCRT bug (not fixed upstream yet). + # With UCRT, printf("%a", 0.0) produces "0x0.0000000000000p+0", + # while other C runtimes produce just "0x0p+0". + # https://developercommunity.visualstudio.com/t/Printf-formatting-of-float-as-hex-prints/1660844 + Feature( + name="win32-broken-printf-a-precision", + when=lambda cfg: "_WIN32" in compilerMacros(cfg) + and not programSucceeds( + cfg, + """ + #include <stdio.h> + #include <string.h> + int main(int, char**) { + char buf[100]; + snprintf(buf, sizeof(buf), "%a", 0.0); + return strcmp(buf, "0x0p+0"); + } + """, + ), + ), + Feature( + name="has-unix-headers", + when=lambda cfg: sourceBuilds( + cfg, + """ + #include <unistd.h> + #include <sys/wait.h> + int main(int, char**) { + int fd[2]; + return pipe(fd); + } + """, + ), + ), + # Whether Bash can run on the executor. + # This is not always the case, for example when running on embedded systems. + # + # For the corner case of bash existing, but it being missing in the path + # set in %{exec} as "--env PATH=one-single-dir", the executor does find + # and executes bash, but bash then can't find any other common shell + # utilities. Test executing "bash -c 'bash --version'" to see if bash + # manages to find binaries to execute. + Feature( + name="executor-has-no-bash", + when=lambda cfg: runScriptExitCode(cfg, ["%{exec} bash -c 'bash --version'"]) != 0, + ), + # Whether module support for the platform is available. + Feature( + name="has-no-cxx-module-support", + # The libc of these platforms have functions with internal linkage. + # This is not allowed per C11 7.1.2 Standard headers/6 + # Any declaration of a library function shall have external linkage. + when=lambda cfg: "__ANDROID__" in compilerMacros(cfg) + or "__FreeBSD__" in compilerMacros(cfg) + or ("_WIN32" in compilerMacros(cfg) and not _mingwSupportsModules(cfg)) + or platform.system().lower().startswith("aix") + # Avoid building on platforms that don't support modules properly. + or not hasCompileFlag(cfg, "-Wno-reserved-module-identifier") + # older versions don't support extern "C++", newer versions don't support main in named module. + or not ( + sourceBuilds( + cfg, + """ + export module test; + extern "C++" int main(int, char**) { return 0; } + """, + ) + or sourceBuilds( + cfg, + """ + export module test; + int main(int, char**) { return 0; } + """, + ) + ), + ), + # The time zone validation tests compare the output of zdump against the + # output generated by <chrono>'s time zone support. + Feature( + name="has-no-zdump", + when=lambda cfg: runScriptExitCode(cfg, ["zdump --version"]) != 0, + ), + Feature( + name="can-create-symlinks", + when=lambda cfg: "_WIN32" not in compilerMacros(cfg) + or programSucceeds( + cfg, + # Creation of symlinks require elevated privileges on Windows unless + # Windows developer mode is enabled. + """ + #include <stdio.h> + #include <windows.h> + int main(int, char**) { + CHAR tempDirPath[MAX_PATH]; + DWORD tempPathRet = GetTempPathA(MAX_PATH, tempDirPath); + if (tempPathRet == 0 || tempPathRet > MAX_PATH) { + return 1; + } + + CHAR tempFilePath[MAX_PATH]; + UINT uRetVal = GetTempFileNameA( + tempDirPath, + "cxx", // Prefix + 0, // Unique=0 also implies file creation. + tempFilePath); + if (uRetVal == 0) { + return 1; + } + + CHAR symlinkFilePath[MAX_PATH]; + int ret = sprintf_s(symlinkFilePath, MAX_PATH, "%s_symlink", tempFilePath); + if (ret == -1) { + DeleteFileA(tempFilePath); + return 1; + } + + // Requires either administrator, or developer mode enabled. + BOOL bCreatedSymlink = CreateSymbolicLinkA(symlinkFilePath, + tempFilePath, + SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE); + if (!bCreatedSymlink) { + DeleteFileA(tempFilePath); + return 1; + } + + DeleteFileA(tempFilePath); + DeleteFileA(symlinkFilePath); + return 0; + } + """, + ), + ), +] diff --git a/libcxx/utils/libcxx/test/features/platform.py b/libcxx/utils/libcxx/test/features/platform.py new file mode 100644 index 0000000..db9d393 --- /dev/null +++ b/libcxx/utils/libcxx/test/features/platform.py @@ -0,0 +1,132 @@ +# ===----------------------------------------------------------------------===## +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# ===----------------------------------------------------------------------===## + +from libcxx.test.dsl import programOutput, Feature, compilerMacros, programSucceeds, AddCompileFlag, sourceBuilds +import platform +import sys + +def _getAndroidDeviceApi(cfg): + return int( + programOutput( + cfg, + r""" + #include <android/api-level.h> + #include <stdio.h> + int main(int, char**) { + printf("%d\n", android_get_device_api_level()); + return 0; + } + """, + ) + ) + +# Add features representing the target platform name: darwin, linux, windows, etc... +features = [ + Feature(name="darwin", when=lambda cfg: "__APPLE__" in compilerMacros(cfg)), + Feature(name="windows", when=lambda cfg: "_WIN32" in compilerMacros(cfg)), + Feature( + name="windows-dll", + when=lambda cfg: "_WIN32" in compilerMacros(cfg) + and sourceBuilds( + cfg, + """ + #include <iostream> + int main(int, char**) { return 0; } + """, + ) + and programSucceeds( + cfg, + """ + #include <iostream> + #include <windows.h> + #include <winnt.h> + int main(int, char**) { + // Get a pointer to a data member that gets linked from the C++ + // library. This must be a data member (functions can get + // thunk inside the calling executable), and must not be + // something that is defined inline in headers. + void *ptr = &std::cout; + // Get a handle to the current main executable. + void *exe = GetModuleHandle(NULL); + // The handle points at the PE image header. Navigate through + // the header structure to find the size of the PE image (the + // executable). + PIMAGE_DOS_HEADER dosheader = (PIMAGE_DOS_HEADER)exe; + PIMAGE_NT_HEADERS ntheader = (PIMAGE_NT_HEADERS)((BYTE *)dosheader + dosheader->e_lfanew); + PIMAGE_OPTIONAL_HEADER peheader = &ntheader->OptionalHeader; + void *exeend = (BYTE*)exe + peheader->SizeOfImage; + // Check if the tested pointer - the data symbol from the + // C++ library - is located within the exe. + if (ptr >= exe && ptr <= exeend) + return 1; + // Return success if it was outside of the executable, i.e. + // loaded from a DLL. + return 0; + } + """, + ), + actions=[AddCompileFlag("-DTEST_WINDOWS_DLL")], + ), + Feature(name="linux", when=lambda cfg: "__linux__" in compilerMacros(cfg)), + Feature(name="android", when=lambda cfg: "__ANDROID__" in compilerMacros(cfg)), + Feature( + name=lambda cfg: "android-device-api={}".format(_getAndroidDeviceApi(cfg)), + when=lambda cfg: "__ANDROID__" in compilerMacros(cfg), + ), + Feature( + name="LIBCXX-ANDROID-FIXME", + when=lambda cfg: "__ANDROID__" in compilerMacros(cfg), + ), + Feature(name="netbsd", when=lambda cfg: "__NetBSD__" in compilerMacros(cfg)), + Feature(name="freebsd", when=lambda cfg: "__FreeBSD__" in compilerMacros(cfg)), + Feature( + name="LIBCXX-FREEBSD-FIXME", + when=lambda cfg: "__FreeBSD__" in compilerMacros(cfg), + ), + Feature( + name="LIBCXX-PICOLIBC-FIXME", + when=lambda cfg: sourceBuilds( + cfg, + """ + #include <string.h> + #ifndef __PICOLIBC__ + #error not picolibc + #endif + int main(int, char**) { return 0; } + """, + ), + ), + Feature( + name="LIBCXX-AMDGPU-FIXME", + when=lambda cfg: "__AMDGPU__" in compilerMacros(cfg), + ), + Feature( + name="LIBCXX-NVPTX-FIXME", + when=lambda cfg: "__NVPTX__" in compilerMacros(cfg), + ), +] + +# Add features representing the build host platform name. +# The build host could differ from the target platform for cross-compilation. +features += [ + Feature(name="buildhost={}".format(sys.platform.lower().strip())), + # sys.platform can often be represented by a "sub-system", such as 'win32', 'cygwin', 'mingw', freebsd13 & etc. + # We define a consolidated feature on a few platforms. + Feature( + name="buildhost=windows", + when=lambda cfg: platform.system().lower().startswith("windows"), + ), + Feature( + name="buildhost=freebsd", + when=lambda cfg: platform.system().lower().startswith("freebsd"), + ), + Feature( + name="buildhost=aix", + when=lambda cfg: platform.system().lower().startswith("aix"), + ), +] diff --git a/libcxx/utils/libcxx/test/format.py b/libcxx/utils/libcxx/test/format.py index 975209c..76e9115 100644 --- a/libcxx/utils/libcxx/test/format.py +++ b/libcxx/utils/libcxx/test/format.py @@ -99,7 +99,7 @@ def parseScript(test, preamble): substitutions.append( ( "%{verify}", - "%{cxx} %s %{flags} %{compile_flags} -fsyntax-only -Wno-error -Xclang -verify -Xclang -verify-ignore-unexpected=note -ferror-limit=0", + "%{cxx} %s %{flags} %{compile_flags} -U_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -fsyntax-only -Wno-error -Xclang -verify -Xclang -verify-ignore-unexpected=note -ferror-limit=0", ) ) substitutions.append(("%{run}", "%{exec} %t.exe")) diff --git a/libcxx/utils/libcxx/test/modules.py b/libcxx/utils/libcxx/test/modules.py index bd4fbe7..b93846b 100644 --- a/libcxx/utils/libcxx/test/modules.py +++ b/libcxx/utils/libcxx/test/modules.py @@ -166,7 +166,7 @@ class module_test_generator: f'" > {self.tmp_prefix}.{header}.cppm' ) - # Extract the information of the module partition using lang-tidy + # Extract the information of the module partition using clang-tidy print( f"// RUN: {self.clang_tidy} {self.tmp_prefix}.{header}.cppm " " --checks='-*,libcpp-header-exportable-declarations' " @@ -222,6 +222,7 @@ class module_test_generator: print(f'// RUN: echo -e "' f"{include}" f'" > {self.tmp_prefix}.{header}.cpp') print( f"// RUN: {self.clang_tidy} {self.tmp_prefix}.{header}.cpp " + " --system-headers " " --checks='-*,libcpp-header-exportable-declarations' " " -config='{CheckOptions: [ " " {" diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py index c02d6df..299aa28 100644 --- a/libcxx/utils/libcxx/test/params.py +++ b/libcxx/utils/libcxx/test/params.py @@ -11,7 +11,7 @@ import shlex from pathlib import Path from libcxx.test.dsl import * -from libcxx.test.features import _isClang, _isAppleClang, _isGCC, _isMSVC +from libcxx.test.features.compiler import _isClang, _isAppleClang, _isGCC, _isMSVC _warningFlags = [ |
