diff --git a/.clang-format b/.clang-format index 0ffd390f783..035d0c1f84b 100644 --- a/.clang-format +++ b/.clang-format @@ -1,13 +1,12 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# https://releases.llvm.org/18.1.8/tools/clang/docs/ClangFormatStyleOptions.html +# https://releases.llvm.org/19.1.0/tools/clang/docs/ClangFormatStyleOptions.html # To update this .clang-format file for a new clang-format version: # 1. Update the documentation link above. -# 2. Copy the output of `clang-format -dump-config` into a temporary file. +# 2. Copy the output of `clang-format -dump-config --style=LLVM` into a temporary file. # a. Comment out all of its lines. -# b. Uncomment `BasedOnStyle: LLVM`. # 3. Compare that temporary file to this .clang-format file. # 4. Adjust this .clang-format file to record new and updated options. # a. Read the new documentation to understand such changes. @@ -56,7 +55,29 @@ AlignConsecutiveMacros: Consecutive # Enabled: false # AcrossEmptyLines: false # AcrossComments: false +# AlignCaseArrows: false # AlignCaseColons: false +# AlignConsecutiveTableGenBreakingDAGArgColons: +# Enabled: false +# AcrossEmptyLines: false +# AcrossComments: false +# AlignCompound: false +# AlignFunctionPointers: false +# PadOperators: false +# AlignConsecutiveTableGenCondOperatorColons: +# Enabled: false +# AcrossEmptyLines: false +# AcrossComments: false +# AlignCompound: false +# AlignFunctionPointers: false +# PadOperators: false +# AlignConsecutiveTableGenDefinitionColons: +# Enabled: false +# AcrossEmptyLines: false +# AcrossComments: false +# AlignCompound: false +# AlignFunctionPointers: false +# PadOperators: false # AlignEscapedNewlines: Right AlignEscapedNewlines: Left # AlignOperands: Align @@ -71,6 +92,7 @@ AlignTrailingComments: # AllowBreakBeforeNoexceptSpecifier: Never AllowBreakBeforeNoexceptSpecifier: OnlyWithParen # AllowShortBlocksOnASingleLine: Never +# AllowShortCaseExpressionOnASingleLine: true # AllowShortCaseLabelsOnASingleLine: false # AllowShortCompoundRequirementOnASingleLine: true # AllowShortEnumsOnASingleLine: true @@ -80,10 +102,7 @@ AllowShortFunctionsOnASingleLine: Empty # AllowShortLambdasOnASingleLine: All # AllowShortLoopsOnASingleLine: false # AlwaysBreakAfterDefinitionReturnType: None -# AlwaysBreakAfterReturnType: None # AlwaysBreakBeforeMultilineStrings: false -# AlwaysBreakTemplateDeclarations: MultiLine -AlwaysBreakTemplateDeclarations: Yes # AttributeMacros: # - __capability # BinPackArguments: true @@ -112,6 +131,7 @@ AlwaysBreakTemplateDeclarations: Yes # BreakAfterAttributes: Leave BreakAfterAttributes: Never # BreakAfterJavaFieldAnnotations: false +# BreakAfterReturnType: None # BreakArrays: true # BreakBeforeBinaryOperators: None BreakBeforeBinaryOperators: NonAssignment @@ -120,8 +140,11 @@ BreakBeforeBinaryOperators: NonAssignment # BreakBeforeInlineASMColon: OnlyMultiline # BreakBeforeTernaryOperators: true # BreakConstructorInitializers: BeforeColon +# BreakFunctionDefinitionParameters: false # BreakInheritanceList: BeforeColon # BreakStringLiterals: true +# BreakTemplateDeclarations: MultiLine +BreakTemplateDeclarations: Yes # ColumnLimit: 80 ColumnLimit: 120 # CommentPragmas: '^ IWYU pragma:' @@ -202,14 +225,19 @@ InsertNewlineAtEOF: true # HexMinDigits: 0 # JavaScriptQuotes: Leave # JavaScriptWrapImports: true -# KeepEmptyLinesAtTheStartOfBlocks: true -# KeepEmptyLinesAtEOF: false +# KeepEmptyLines: +# AtEndOfFile: false +# AtStartOfBlock: true +# AtStartOfFile: true +KeepEmptyLines: + AtStartOfFile: false # LambdaBodyIndentation: Signature # LineEnding: DeriveLF LineEnding: CRLF # NOTE: MacroBlockBegin/MacroBlockEnd don't work with _CATCH_ALL. # MacroBlockBegin: '' # MacroBlockEnd: '' +# MainIncludeChar: Quote # MaxEmptyLinesToKeep: 1 MaxEmptyLinesToKeep: 2 # NamespaceIndentation: None @@ -286,6 +314,7 @@ SpaceBeforeParensOptions: # Maximum: -1 # SpacesInParens: Never # SpacesInParensOptions: +# ExceptDoubleParentheses: false # InCStyleCasts: false # InConditionalStatements: false # InEmptyParentheses: false @@ -310,6 +339,7 @@ StatementMacros: - _FMT_P2286_END - _EXTERN_C_UNLESS_PURE - _END_EXTERN_C_UNLESS_PURE +# TableGenBreakInsideDAGArg: DontBreak # TabWidth: 8 # UseTab: Never # VerilogBreakBetweenInstancePorts: true diff --git a/README.md b/README.md index de703daad4e..2ed5d8af157 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ issue. The [bug tag][] and [enhancement tag][] are being populated. # Goals -We're implementing the latest C++ Working Draft, currently [N4993][], which will eventually become the next C++ +We're implementing the latest C++ Working Draft, currently [N5001][], which will eventually become the next C++ International Standard. The terms Working Draft (WD) and Working Paper (WP) are interchangeable; we often informally refer to these drafts as "the Standard" while being aware of the difference. (There are other relevant Standards; for example, supporting `/std:c++14` and `/std:c++17` involves understanding how the C++14 and C++17 @@ -141,7 +141,7 @@ Just try to follow these rules, so we can spend more time fixing bugs and implem # How To Build With The Visual Studio IDE -1. Install Visual Studio 2022 17.13 Preview 2 or later. +1. Install Visual Studio 2022 17.13 Preview 3 or later. * Select "Windows 11 SDK (10.0.22621.0)" in the VS Installer. * Select "MSVC v143 - VS 2022 C++ ARM64/ARM64EC build tools (Latest)" in the VS Installer if you would like to build the ARM64/ARM64EC target. @@ -160,7 +160,7 @@ Just try to follow these rules, so we can spend more time fixing bugs and implem # How To Build With A Native Tools Command Prompt -1. Install Visual Studio 2022 17.13 Preview 2 or later. +1. Install Visual Studio 2022 17.13 Preview 3 or later. * Select "Windows 11 SDK (10.0.22621.0)" in the VS Installer. * Select "MSVC v143 - VS 2022 C++ ARM64/ARM64EC build tools (Latest)" in the VS Installer if you would like to build the ARM64/ARM64EC target. @@ -412,7 +412,8 @@ set PATH=C:\STL\out\x64\out\bin\amd64;%PATH% ## Running Tests With Address Sanitizer (ASan) You don't need any extra steps to run with test code and the code in STL headers instrumented with [ASan][]. -The test matrices include both ASan and non-ASan configurations. +The test matrices include both ASan and non-ASan configurations if you don't pass `-Dtags=ASAN` or `-Dnotags=ASAN` +to exclude one or the other. However, to instrument the separately-compiled code (the DLL, the satellites, the [Import Library][] - everything that's in `/stl/src`), you need to build the STL with ASan. Change the build steps to add `-DSTL_ASAN_BUILD=ON`: @@ -425,6 +426,8 @@ cmake --build --preset x64 ASan-instrumented STL binaries require that the executable be instrumented as well, so you'll have to skip the non-ASan configurations by passing `-Dtags=ASAN` to `stl-lit.py`: +(This example assumes that your current directory is `C:\Dev\STL\out\x64`.) + ``` python tests\utils\stl-lit\stl-lit.py ..\..\tests\std\tests\VSO_0000000_vector_algorithms -Dtags=ASAN -v ``` @@ -565,7 +568,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception [LWG issues]: https://cplusplus.github.io/LWG/lwg-toc.html [LWG tag]: https://github.com/microsoft/STL/issues?q=is%3Aopen+is%3Aissue+label%3ALWG [Microsoft Open Source Code of Conduct]: https://opensource.microsoft.com/codeofconduct/ -[N4993]: https://wg21.link/N4993 +[N5001]: https://wg21.link/N5001 [NOTICE.txt]: NOTICE.txt [Ninja]: https://ninja-build.org [STL-CI-badge]: https://dev.azure.com/vclibs/STL/_apis/build/status%2FSTL-CI?branchName=main "STL-CI" diff --git a/azure-devops/config.yml b/azure-devops/config.yml index ca89e088cf8..111b6eab4f3 100644 --- a/azure-devops/config.yml +++ b/azure-devops/config.yml @@ -5,7 +5,7 @@ variables: - name: poolName - value: 'StlBuild-2024-12-12T1002-Pool' + value: 'StlBuild-2025-01-22T1525-Pool' readonly: true - name: poolDemands value: 'EnableSpotVM -equals false' diff --git a/azure-devops/provision-image.ps1 b/azure-devops/provision-image.ps1 index 048bbd65d75..630b6676dd4 100644 --- a/azure-devops/provision-image.ps1 +++ b/azure-devops/provision-image.ps1 @@ -47,7 +47,7 @@ $PythonUrl = 'https://www.python.org/ftp/python/3.13.1/python-3.13.1-amd64.exe' $PythonArgs = @('/quiet', 'InstallAllUsers=1', 'PrependPath=1', 'CompileAll=1', 'Include_doc=0') $CudaUrl = 'https://developer.download.nvidia.com/compute/cuda/12.4.0/local_installers/cuda_12.4.0_551.61_windows.exe' -$CudaArgs = @('-s') +$CudaArgs = @('-s', '-n', 'nvcc_12.4') <# .SYNOPSIS diff --git a/llvm-project b/llvm-project index 69ead949d08..63d3bd6d0ca 160000 --- a/llvm-project +++ b/llvm-project @@ -1 +1 @@ -Subproject commit 69ead949d08ff0bb8cbbf4f7143aaa6687830f6b +Subproject commit 63d3bd6d0caf8185aba49540fe2f67512fdf3a98 diff --git a/stl/inc/__msvc_heap_algorithms.hpp b/stl/inc/__msvc_heap_algorithms.hpp index 3a06b593456..f368fc70954 100644 --- a/stl/inc/__msvc_heap_algorithms.hpp +++ b/stl/inc/__msvc_heap_algorithms.hpp @@ -23,8 +23,8 @@ _CONSTEXPR20 void _Push_heap_by_index( _RanIt _First, _Iter_diff_t<_RanIt> _Hole, _Iter_diff_t<_RanIt> _Top, _Ty&& _Val, _Pr _Pred) { // percolate _Hole to _Top or where _Val belongs using _Diff = _Iter_diff_t<_RanIt>; - for (_Diff _Idx = (_Hole - 1) >> 1; // shift for codegen - _Top < _Hole && _DEBUG_LT_PRED(_Pred, *(_First + _Idx), _Val); _Idx = (_Hole - 1) >> 1) { // shift for codegen + for (_Diff _Idx = (_Hole - 1) >> 1; // shift for codegen + _Top < _Hole && _DEBUG_LT_PRED(_Pred, *(_First + _Idx), _Val); _Idx = (_Hole - 1) >> 1) { // shift for codegen // move _Hole up to parent *(_First + _Hole) = _STD move(*(_First + _Idx)); _Hole = _Idx; diff --git a/stl/inc/__msvc_int128.hpp b/stl/inc/__msvc_int128.hpp index 9a3f2e3c69b..7933e595820 100644 --- a/stl/inc/__msvc_int128.hpp +++ b/stl/inc/__msvc_int128.hpp @@ -23,7 +23,8 @@ #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv #define _TEMPLATE_CLASS_INTEGRAL(type) template , int> = 0> #define _ZERO_OR_NO_INIT \ - {} // Trivial default initialization is not allowed in constexpr functions before C++20. + { \ + } // Trivial default initialization is not allowed in constexpr functions before C++20. #endif // ^^^ !_HAS_CXX20 ^^^ #pragma pack(push, _CRT_PACKING) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index 57fc646177e..14198cbdf6b 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -1344,9 +1344,10 @@ class basic_string_view { // wrapper for any kind of contiguous character buffer "Bad char_traits for basic_string_view; N4950 [string.view.template.general]/1 " "\"The program is ill-formed if traits::char_type is not the same type as charT.\""); - static_assert(!is_array_v<_Elem> && is_trivial_v<_Elem> && is_standard_layout_v<_Elem>, - "The character type of basic_string_view must be a non-array trivial standard-layout type. See N4950 " - "[strings.general]/1."); + static_assert(!is_array_v<_Elem> && is_trivially_copyable_v<_Elem> && is_trivially_default_constructible_v<_Elem> + && is_standard_layout_v<_Elem>, + "The character type of basic_string_view must be a non-array trivially copyable standard-layout type T where " + "is_trivially_default_constructible_v is true. See N5001 [strings.general]/1."); using traits_type = _Traits; using value_type = _Elem; diff --git a/stl/inc/atomic b/stl/inc/atomic index 9f4da0a47e3..e69bb281481 100644 --- a/stl/inc/atomic +++ b/stl/inc/atomic @@ -468,12 +468,13 @@ struct _Atomic_storage; template void _Atomic_wait_direct( const _Atomic_storage<_Ty>* const _This, _Value_type _Expected_bytes, const memory_order _Order) noexcept { - const auto _Storage_ptr = _STD addressof(_This->_Storage); + const auto _Storage_ptr = + const_cast(static_cast(_STD addressof(_This->_Storage))); for (;;) { const _Value_type _Observed_bytes = _STD _Atomic_reinterpret_as<_Value_type>(_This->load(_Order)); if (_Expected_bytes != _Observed_bytes) { #if _CMPXCHG_MASK_OUT_PADDING_BITS - using _TVal = remove_reference_t<_Ty>; + using _TVal = _Remove_cvref_t<_Ty>; if constexpr (_Might_have_non_value_bits<_TVal>) { _Storage_for<_TVal> _Mask{_Form_mask}; const _Value_type _Mask_val = _STD _Atomic_reinterpret_as<_Value_type>(_Mask._Ref()); @@ -581,7 +582,7 @@ struct _Atomic_storage { // Provides operations common to all specializations of std::atomic, load, store, exchange, and CAS. // Locking version used when hardware has no atomic operations for sizeof(_Ty). - using _TVal = remove_reference_t<_Ty>; + using _TVal = _Remove_cvref_t<_Ty>; using _Guard = _Atomic_lock_guard::_Spinlock>; _Atomic_storage() = default; @@ -713,7 +714,7 @@ public: template struct _Atomic_storage<_Ty, 1> { // lock-free using 1-byte intrinsics - using _TVal = remove_reference_t<_Ty>; + using _TVal = _Remove_cvref_t<_Ty>; _Atomic_storage() = default; @@ -801,11 +802,13 @@ struct _Atomic_storage<_Ty, 1> { // lock-free using 1-byte intrinsics } void notify_one() noexcept { - ::__std_atomic_notify_one_direct(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_one_direct(_Storage_ptr); } void notify_all() noexcept { - ::__std_atomic_notify_all_direct(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_all_direct(_Storage_ptr); } #endif // _HAS_CXX20 @@ -814,7 +817,7 @@ struct _Atomic_storage<_Ty, 1> { // lock-free using 1-byte intrinsics template struct _Atomic_storage<_Ty, 2> { // lock-free using 2-byte intrinsics - using _TVal = remove_reference_t<_Ty>; + using _TVal = _Remove_cvref_t<_Ty>; _Atomic_storage() = default; @@ -901,11 +904,13 @@ struct _Atomic_storage<_Ty, 2> { // lock-free using 2-byte intrinsics } void notify_one() noexcept { - ::__std_atomic_notify_one_direct(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_one_direct(_Storage_ptr); } void notify_all() noexcept { - ::__std_atomic_notify_all_direct(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_all_direct(_Storage_ptr); } #endif // _HAS_CXX20 @@ -914,7 +919,7 @@ struct _Atomic_storage<_Ty, 2> { // lock-free using 2-byte intrinsics template struct _Atomic_storage<_Ty, 4> { // lock-free using 4-byte intrinsics - using _TVal = remove_reference_t<_Ty>; + using _TVal = _Remove_cvref_t<_Ty>; _Atomic_storage() = default; @@ -1001,11 +1006,13 @@ struct _Atomic_storage<_Ty, 4> { // lock-free using 4-byte intrinsics } void notify_one() noexcept { - ::__std_atomic_notify_one_direct(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_one_direct(_Storage_ptr); } void notify_all() noexcept { - ::__std_atomic_notify_all_direct(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_all_direct(_Storage_ptr); } #endif // _HAS_CXX20 @@ -1014,7 +1021,7 @@ struct _Atomic_storage<_Ty, 4> { // lock-free using 4-byte intrinsics template struct _Atomic_storage<_Ty, 8> { // lock-free using 8-byte intrinsics - using _TVal = remove_reference_t<_Ty>; + using _TVal = _Remove_cvref_t<_Ty>; _Atomic_storage() = default; @@ -1120,11 +1127,13 @@ struct _Atomic_storage<_Ty, 8> { // lock-free using 8-byte intrinsics } void notify_one() noexcept { - ::__std_atomic_notify_one_direct(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_one_direct(_Storage_ptr); } void notify_all() noexcept { - ::__std_atomic_notify_all_direct(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_all_direct(_Storage_ptr); } #endif // _HAS_CXX20 @@ -1135,7 +1144,7 @@ struct _Atomic_storage<_Ty, 8> { // lock-free using 8-byte intrinsics template struct _Atomic_storage<_Ty&, 16> { // lock-free using 16-byte intrinsics // TRANSITION, ABI: replace '_Ty&' with '_Ty' in this specialization - using _TVal = remove_reference_t<_Ty&>; + using _TVal = _Remove_cvref_t<_Ty&>; _Atomic_storage() = default; @@ -1252,8 +1261,8 @@ struct _Atomic_storage<_Ty&, 16> { // lock-free using 16-byte intrinsics &_Expected_temp._Low); #else // ^^^ _M_ARM64, _M_ARM64EC / _M_X64 vvv (void) _Order; - _Result = _InterlockedCompareExchange128( - &reinterpret_cast(_Storage), _Desired_bytes._High, _Desired_bytes._Low, &_Expected_temp._Low); + _Result = _InterlockedCompareExchange128(&reinterpret_cast(_Storage), _Desired_bytes._High, + _Desired_bytes._Low, &_Expected_temp._Low); #endif // ^^^ _M_X64 ^^^ if (_Result == 0) { _CSTD memcpy(_STD addressof(_Expected), &_Expected_temp, sizeof(_TVal)); @@ -1264,7 +1273,7 @@ struct _Atomic_storage<_Ty&, 16> { // lock-free using 16-byte intrinsics #if _HAS_CXX20 void wait(_TVal _Expected, memory_order _Order = memory_order_seq_cst) const noexcept { - const auto _Storage_ptr = _STD addressof(_Storage); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); const auto _Expected_ptr = _STD addressof(_Expected); _Int128 _Expected_bytes = reinterpret_cast(_Expected); @@ -1294,11 +1303,13 @@ struct _Atomic_storage<_Ty&, 16> { // lock-free using 16-byte intrinsics } void notify_one() noexcept { - ::__std_atomic_notify_one_indirect(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_one_indirect(_Storage_ptr); } void notify_all() noexcept { - ::__std_atomic_notify_all_indirect(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_all_indirect(_Storage_ptr); } #endif // _HAS_CXX20 @@ -1615,9 +1626,18 @@ constexpr bool _Deprecate_non_lock_free_volatile = true; template _CXX20_DEPRECATE_VOLATILE constexpr bool _Deprecate_non_lock_free_volatile<_Ty, false> = true; +#if _HAS_CXX20 +#define _REQUIRES_CLAUSE(...) requires (__VA_ARGS__) +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv +#define _REQUIRES_CLAUSE(...) +#endif // ^^^ !_HAS_CXX20 ^^^ + template struct _Atomic_integral_facade : _Atomic_integral<_Ty> { // provides operator overloads and other support for atomic integral specializations + _STL_INTERNAL_STATIC_ASSERT(!is_const_v<_Ty>); + _STL_INTERNAL_STATIC_ASSERT(!is_volatile_v<_Ty>); + using _Base = _Atomic_integral<_Ty>; using difference_type = _Ty; @@ -1747,88 +1767,89 @@ template struct _Atomic_integral_facade<_Ty&> : _Atomic_integral<_Ty&> { // provides operator overloads and other support for atomic integral specializations using _Base = _Atomic_integral<_Ty&>; - using difference_type = _Ty; + using difference_type = remove_cv_t<_Ty>; + using typename _Base::_TVal; using _Base::_Base; - _NODISCARD static _Ty _Negate(const _Ty _Value) noexcept { // returns two's complement negated value of _Value - return static_cast<_Ty>(0U - static_cast>(_Value)); + _NODISCARD static _TVal _Negate(const _TVal _Value) noexcept { // returns two's complement negated value of _Value + return static_cast<_TVal>(0U - static_cast>(_Value)); } - _Ty fetch_add(const _Ty _Operand) const noexcept { + _TVal fetch_add(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::fetch_add(_Operand); } - _Ty fetch_add(const _Ty _Operand, const memory_order _Order) const noexcept { + _TVal fetch_add(const _TVal _Operand, const memory_order _Order) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::fetch_add(_Operand, _Order); } - _Ty fetch_sub(const _Ty _Operand) const noexcept { + _TVal fetch_sub(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(_Negate(_Operand)); } - _Ty fetch_sub(const _Ty _Operand, const memory_order _Order) const noexcept { + _TVal fetch_sub(const _TVal _Operand, const memory_order _Order) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(_Negate(_Operand), _Order); } - _Ty operator++(int) const noexcept { + _TVal operator++(int) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::operator++(0); } - _Ty operator++() const noexcept { + _TVal operator++() const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::operator++(); } - _Ty operator--(int) const noexcept { + _TVal operator--(int) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::operator--(0); } - _Ty operator--() const noexcept { + _TVal operator--() const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::operator--(); } - _Ty operator+=(const _Ty _Operand) const noexcept { - return static_cast<_Ty>(fetch_add(_Operand) + _Operand); + _TVal operator+=(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { + return static_cast<_TVal>(fetch_add(_Operand) + _Operand); } - _Ty operator-=(const _Ty _Operand) const noexcept { - return static_cast<_Ty>(fetch_sub(_Operand) - _Operand); + _TVal operator-=(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { + return static_cast<_TVal>(fetch_sub(_Operand) - _Operand); } - _Ty fetch_and(const _Ty _Operand) const noexcept { + _TVal fetch_and(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::fetch_and(_Operand); } - _Ty fetch_and(const _Ty _Operand, const memory_order _Order) const noexcept { + _TVal fetch_and(const _TVal _Operand, const memory_order _Order) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::fetch_and(_Operand, _Order); } - _Ty fetch_or(const _Ty _Operand) const noexcept { + _TVal fetch_or(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::fetch_or(_Operand); } - _Ty fetch_or(const _Ty _Operand, const memory_order _Order) const noexcept { + _TVal fetch_or(const _TVal _Operand, const memory_order _Order) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::fetch_or(_Operand, _Order); } - _Ty fetch_xor(const _Ty _Operand) const noexcept { + _TVal fetch_xor(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::fetch_xor(_Operand); } - _Ty fetch_xor(const _Ty _Operand, const memory_order _Order) const noexcept { + _TVal fetch_xor(const _TVal _Operand, const memory_order _Order) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::fetch_xor(_Operand, _Order); } - _Ty operator&=(const _Ty _Operand) const noexcept { - return static_cast<_Ty>(fetch_and(_Operand) & _Operand); + _TVal operator&=(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { + return static_cast<_TVal>(fetch_and(_Operand) & _Operand); } - _Ty operator|=(const _Ty _Operand) const noexcept { - return static_cast<_Ty>(fetch_or(_Operand) | _Operand); + _TVal operator|=(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { + return static_cast<_TVal>(fetch_or(_Operand) | _Operand); } - _Ty operator^=(const _Ty _Operand) const noexcept { - return static_cast<_Ty>(fetch_xor(_Operand) ^ _Operand); + _TVal operator^=(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { + return static_cast<_TVal>(fetch_xor(_Operand) ^ _Operand); } }; @@ -1836,6 +1857,9 @@ struct _Atomic_integral_facade<_Ty&> : _Atomic_integral<_Ty&> { template struct _Atomic_floating : _Atomic_storage<_Ty> { // provides atomic floating-point operations + _STL_INTERNAL_STATIC_ASSERT(!is_const_v<_Ty>); + _STL_INTERNAL_STATIC_ASSERT(!is_volatile_v<_Ty>); + using _Base = _Atomic_storage<_Ty>; using difference_type = _Ty; @@ -1891,12 +1915,15 @@ template struct _Atomic_floating<_Ty&> : _Atomic_storage<_Ty&> { // provides atomic floating-point operations using _Base = _Atomic_storage<_Ty&>; - using difference_type = _Ty; + using difference_type = remove_cv_t<_Ty>; + using typename _Base::_TVal; using _Base::_Base; - _Ty fetch_add(const _Ty _Operand, const memory_order _Order = memory_order_seq_cst) const noexcept { - _Ty _Temp{this->load(memory_order_relaxed)}; + _TVal fetch_add(const _TVal _Operand, const memory_order _Order = memory_order_seq_cst) const noexcept + requires (!is_const_v<_Ty>) + { + _TVal _Temp{this->load(memory_order_relaxed)}; while (!const_cast<_Atomic_floating*>(this)->_Base::compare_exchange_strong( _Temp, _Temp + _Operand, _Order)) { // keep trying } @@ -1904,8 +1931,10 @@ struct _Atomic_floating<_Ty&> : _Atomic_storage<_Ty&> { return _Temp; } - _Ty fetch_sub(const _Ty _Operand, const memory_order _Order = memory_order_seq_cst) const noexcept { - _Ty _Temp{this->load(memory_order_relaxed)}; + _TVal fetch_sub(const _TVal _Operand, const memory_order _Order = memory_order_seq_cst) const noexcept + requires (!is_const_v<_Ty>) + { + _TVal _Temp{this->load(memory_order_relaxed)}; while (!const_cast<_Atomic_floating*>(this)->_Base::compare_exchange_strong( _Temp, _Temp - _Operand, _Order)) { // keep trying } @@ -1913,11 +1942,15 @@ struct _Atomic_floating<_Ty&> : _Atomic_storage<_Ty&> { return _Temp; } - _Ty operator+=(const _Ty _Operand) const noexcept { + _TVal operator+=(const _TVal _Operand) const noexcept + requires (!is_const_v<_Ty>) + { return fetch_add(_Operand) + _Operand; } - _Ty operator-=(const _Ty _Operand) const noexcept { + _TVal operator-=(const _TVal _Operand) const noexcept + requires (!is_const_v<_Ty>) + { return fetch_sub(_Operand) - _Operand; } }; @@ -2023,10 +2056,12 @@ template struct _Atomic_pointer<_Ty&> : _Atomic_storage<_Ty&> { using _Base = _Atomic_storage<_Ty&>; using difference_type = ptrdiff_t; + using typename _Base::_TVal; using _Base::_Base; - _Ty fetch_add(const ptrdiff_t _Diff, const memory_order _Order = memory_order_seq_cst) const noexcept { + _TVal fetch_add(const ptrdiff_t _Diff, const memory_order _Order = memory_order_seq_cst) const noexcept + _REQUIRES_CLAUSE(!is_const_v<_Ty>) { const ptrdiff_t _Shift_bytes = static_cast(static_cast(_Diff) * sizeof(remove_pointer_t<_Ty>)); ptrdiff_t _Result; @@ -2037,42 +2072,45 @@ struct _Atomic_pointer<_Ty&> : _Atomic_storage<_Ty&> { _ATOMIC_CHOOSE_INTRINSIC(static_cast(_Order), _Result, _InterlockedExchangeAdd64, _STD _Atomic_address_as(this->_Storage), _Shift_bytes); #endif // ^^^ 64 bits ^^^ - return reinterpret_cast<_Ty>(_Result); + return reinterpret_cast<_TVal>(_Result); } - _Ty fetch_sub(const ptrdiff_t _Diff) const noexcept { + _TVal fetch_sub(const ptrdiff_t _Diff) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(static_cast(0 - static_cast(_Diff))); } - _Ty fetch_sub(const ptrdiff_t _Diff, const memory_order _Order) const noexcept { + _TVal fetch_sub(const ptrdiff_t _Diff, const memory_order _Order) const noexcept + _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(static_cast(0 - static_cast(_Diff)), _Order); } - _Ty operator++(int) const noexcept { + _TVal operator++(int) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(1); } - _Ty operator++() const noexcept { + _TVal operator++() const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(1) + 1; } - _Ty operator--(int) const noexcept { + _TVal operator--(int) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(-1); } - _Ty operator--() const noexcept { + _TVal operator--() const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(-1) - 1; } - _Ty operator+=(const ptrdiff_t _Diff) const noexcept { + _TVal operator+=(const ptrdiff_t _Diff) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(_Diff) + _Diff; } - _Ty operator-=(const ptrdiff_t _Diff) const noexcept { + _TVal operator-=(const ptrdiff_t _Diff) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(static_cast(0 - static_cast(_Diff))) - _Diff; } }; +#undef _REQUIRES_CLAUSE + template struct _Atomic_nonobject_pointer : _Atomic_storage<_Ty> { using _Base = _Atomic_storage<_Ty>; @@ -2081,15 +2119,22 @@ struct _Atomic_nonobject_pointer : _Atomic_storage<_Ty> { using _Base::_Base; }; +template +struct _Atomic_nonobject_pointer<_Ty&> : _Atomic_storage<_Ty&> { + using _Base = _Atomic_storage<_Ty&>; + + using _Base::_Base; +}; + #define ATOMIC_VAR_INIT(_Value) {_Value} template using _Choose_atomic_base2_t = - typename _Select && !is_same_v>::template _Apply<_Atomic_integral_facade<_Ty>, - typename _Select>::template _Apply< - typename _Select>>::template _Apply<_Atomic_pointer<_Ty>, - _Atomic_nonobject_pointer<_Ty>>, - _Atomic_storage<_Ty>>>; + typename _Select && !is_same_v>>::template _Apply< + _Atomic_integral_facade<_Ty>, typename _Select>::template _Apply< + typename _Select>>::template _Apply< + _Atomic_pointer<_Ty>, _Atomic_nonobject_pointer<_Ty>>, + _Atomic_storage<_Ty>>>; #if _HAS_CXX20 template @@ -2106,10 +2151,13 @@ private: using _Base = _Choose_atomic_base_t<_Ty>; public: - static_assert(is_trivially_copyable_v<_Ty> && is_copy_constructible_v<_Ty> && is_move_constructible_v<_Ty> - && is_copy_assignable_v<_Ty> && is_move_assignable_v<_Ty>, - "atomic requires T to be trivially copyable, copy constructible, move constructible, copy assignable, " - "and move assignable."); + static_assert(is_trivially_copyable_v<_Ty>, "atomic requires T to be trivially copyable."); + static_assert(is_copy_constructible_v<_Ty>, "atomic requires T to be copy constructible."); + static_assert(is_move_constructible_v<_Ty>, "atomic requires T to be move constructible."); + static_assert(is_copy_assignable_v<_Ty>, "atomic requires T to be copy assignable."); + static_assert(is_move_assignable_v<_Ty>, "atomic requires T to be move assignable."); + static_assert(!is_const_v<_Ty>, "atomic requires T to be non-const."); + static_assert(!is_volatile_v<_Ty>, "atomic requires T to be non-volatile."); using value_type = _Ty; @@ -2276,7 +2324,7 @@ private: public: static_assert(is_trivially_copyable_v<_Ty>, "atomic_ref requires T to be trivially copyable."); - using value_type = _Ty; + using value_type = remove_cv_t<_Ty>; explicit atomic_ref(_Ty& _Value) noexcept /* strengthened */ : _Base(_Value) { if constexpr (is_always_lock_free) { @@ -2295,66 +2343,97 @@ public: static constexpr size_t required_alignment = is_always_lock_free ? sizeof(_Ty) : alignof(_Ty); + static_assert(is_always_lock_free || !is_volatile_v<_Ty>, + "atomic_ref requires T to be non-volatile when it is not always lock-free."); + _NODISCARD bool is_lock_free() const noexcept { return is_always_lock_free; } - void store(const _Ty _Value) const noexcept { + void store(const value_type _Value) const noexcept + requires (!is_const_v<_Ty>) + { const_cast(this)->_Base::store(_Value); } - void store(const _Ty _Value, const memory_order _Order) const noexcept { + void store(const value_type _Value, const memory_order _Order) const noexcept + requires (!is_const_v<_Ty>) + { const_cast(this)->_Base::store(_Value, _Order); } - _Ty operator=(const _Ty _Value) const noexcept { + value_type operator=(const value_type _Value) const noexcept + requires (!is_const_v<_Ty>) + { store(_Value); return _Value; } - _Ty exchange(const _Ty _Value) const noexcept { + value_type exchange(const value_type _Value) const noexcept + requires (!is_const_v<_Ty>) + { return const_cast(this)->_Base::exchange(_Value); } - _Ty exchange(const _Ty _Value, const memory_order _Order) const noexcept { + value_type exchange(const value_type _Value, const memory_order _Order) const noexcept + requires (!is_const_v<_Ty>) + { return const_cast(this)->_Base::exchange(_Value, _Order); } - bool compare_exchange_strong(_Ty& _Expected, const _Ty _Desired) const noexcept { + bool compare_exchange_strong(value_type& _Expected, const value_type _Desired) const noexcept + requires (!is_const_v<_Ty>) + { return const_cast(this)->_Base::compare_exchange_strong(_Expected, _Desired); } - bool compare_exchange_strong(_Ty& _Expected, const _Ty _Desired, const memory_order _Order) const noexcept { + bool compare_exchange_strong( + value_type& _Expected, const value_type _Desired, const memory_order _Order) const noexcept + requires (!is_const_v<_Ty>) + { return const_cast(this)->_Base::compare_exchange_strong(_Expected, _Desired, _Order); } - bool compare_exchange_strong( - _Ty& _Expected, const _Ty _Desired, const memory_order _Success, const memory_order _Failure) const noexcept { + bool compare_exchange_strong(value_type& _Expected, const value_type _Desired, const memory_order _Success, + const memory_order _Failure) const noexcept + requires (!is_const_v<_Ty>) + { return compare_exchange_strong(_Expected, _Desired, _Combine_cas_memory_orders(_Success, _Failure)); } - bool compare_exchange_weak(_Ty& _Expected, const _Ty _Desired) const noexcept { + bool compare_exchange_weak(value_type& _Expected, const value_type _Desired) const noexcept + requires (!is_const_v<_Ty>) + { return compare_exchange_strong(_Expected, _Desired); } - bool compare_exchange_weak(_Ty& _Expected, const _Ty _Desired, const memory_order _Order) const noexcept { + bool compare_exchange_weak( + value_type& _Expected, const value_type _Desired, const memory_order _Order) const noexcept + requires (!is_const_v<_Ty>) + { return compare_exchange_strong(_Expected, _Desired, _Order); } - bool compare_exchange_weak( - _Ty& _Expected, const _Ty _Desired, const memory_order _Success, const memory_order _Failure) const noexcept { + bool compare_exchange_weak(value_type& _Expected, const value_type _Desired, const memory_order _Success, + const memory_order _Failure) const noexcept + requires (!is_const_v<_Ty>) + { return compare_exchange_strong(_Expected, _Desired, _Combine_cas_memory_orders(_Success, _Failure)); } - operator _Ty() const noexcept { + operator value_type() const noexcept { return this->load(); } - void notify_one() const noexcept { + void notify_one() const noexcept + requires (!is_const_v<_Ty>) + { const_cast(this)->_Base::notify_one(); } - void notify_all() const noexcept { + void notify_all() const noexcept + requires (!is_const_v<_Ty>) + { const_cast(this)->_Base::notify_all(); } @@ -2738,7 +2817,8 @@ _EXPORT_STD using atomic_unsigned_lock_free = atomic_uintptr_t; #endif // _HAS_CXX20 #define ATOMIC_FLAG_INIT \ - {} + { \ + } _EXPORT_STD struct atomic_flag { // flag with test-and-set semantics #if _HAS_CXX20 diff --git a/stl/inc/compare b/stl/inc/compare index adc7730731a..37f9f7f40a2 100644 --- a/stl/inc/compare +++ b/stl/inc/compare @@ -282,9 +282,9 @@ inline constexpr unsigned char _Classify_category = _Comparison _EXPORT_STD template using common_comparison_category_t = - conditional_t<(_Classify_category<_Types...> & _Comparison_category_none) != 0, void, - conditional_t<(_Classify_category<_Types...> & _Comparison_category_partial) != 0, partial_ordering, - conditional_t<(_Classify_category<_Types...> & _Comparison_category_weak) != 0, weak_ordering, + conditional_t<((_Classify_category<_Types...> & _Comparison_category_none) != 0), void, + conditional_t<((_Classify_category<_Types...> & _Comparison_category_partial) != 0), partial_ordering, + conditional_t<((_Classify_category<_Types...> & _Comparison_category_weak) != 0), weak_ordering, strong_ordering>>>; _EXPORT_STD template diff --git a/stl/inc/deque b/stl/inc/deque index eed80fc0993..9bba528c614 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -1012,7 +1012,7 @@ public: // deallocate unused blocks, traversing over the circular buffer until the first used block index for (auto _Block_idx = _First_unused_block_idx; _Block_idx != _First_used_block_idx; - _Block_idx = static_cast((_Block_idx + 1) & _Mask)) { + _Block_idx = static_cast((_Block_idx + 1) & _Mask)) { auto& _Block_ptr = _Map()[static_cast<_Map_difference_type>(_Block_idx)]; if (_Block_ptr != nullptr) { _Getal().deallocate(_Block_ptr, _Block_size); diff --git a/stl/inc/execution b/stl/inc/execution index 8f9ed7b5501..5f5134f768f 100644 --- a/stl/inc/execution +++ b/stl/inc/execution @@ -500,7 +500,8 @@ struct _Parallel_choose_max_chunk { template struct alignas(_Ty) alignas(size_t) alignas(_Atomic_counter_t) _Circular_buffer { // work stealing deque extent type - static_assert(is_trivial_v<_Ty>, "Work stealing deques work only with trivial operations"); + static_assert(is_trivially_copyable_v<_Ty> && is_trivially_default_constructible_v<_Ty>, + "Work stealing deques work only with trivial operations"); size_t _Log_size; _Atomic_counter_t _Ref_count; @@ -676,7 +677,9 @@ public: private: atomic _Bottom{0}; // modified by only owning thread atomic _Top{0}; // modified by all threads + // clang-format off: clang-format 19 doesn't understand _Guarded_by_ and will damage the following code _Guarded_by_(_Segment_lock) _Circular_buffer<_Ty>* _Segment { _Circular_buffer<_Ty>::_New_circular_buffer() }; + // clang-format on mutex _Segment_lock{}; }; diff --git a/stl/inc/expected b/stl/inc/expected index 79e934a52cd..f27e3fc7007 100644 --- a/stl/inc/expected +++ b/stl/inc/expected @@ -304,7 +304,7 @@ public: } } - template + template > requires (!is_same_v, in_place_t> && !is_same_v, expected> && !_Is_specialization_v, unexpected> && (!is_same_v, bool> @@ -469,7 +469,7 @@ public: && _Trivially_move_constructible_assignable_destructible<_Err> = default; - template + template > requires (!is_same_v, expected> && !_Is_specialization_v, unexpected> && is_constructible_v<_Ty, _Uty> && is_assignable_v<_Ty&, _Uty> && (is_nothrow_constructible_v<_Ty, _Uty> || is_nothrow_move_constructible_v<_Ty> @@ -730,32 +730,38 @@ public: return _STD move(_Unexpected); } - template - _NODISCARD constexpr _Ty value_or(_Uty&& _Other) const& noexcept( - is_nothrow_copy_constructible_v<_Ty> && is_nothrow_convertible_v<_Uty, _Ty>) /* strengthened */ { - static_assert( - is_copy_constructible_v<_Ty>, "is_copy_constructible_v must be true. (N4950 [expected.object.obs]/18)"); - static_assert( - is_convertible_v<_Uty, _Ty>, "is_convertible_v must be true. (N4950 [expected.object.obs]/18)"); + template > + _NODISCARD constexpr remove_cv_t<_Ty> value_or(_Uty&& _Other) const& noexcept( + is_nothrow_convertible_v> + && is_nothrow_convertible_v<_Uty, remove_cv_t<_Ty>>) /* strengthened */ { + static_assert(is_convertible_v>, + "is_convertible_v> must be true. " + "(N5001 [expected.object.obs]/18 as modified by LWG-3424)"); + static_assert(is_convertible_v<_Uty, remove_cv_t<_Ty>>, + "is_convertible_v> must be true. " + "(N5001 [expected.object.obs]/18 as modified by LWG-3424)"); if (_Has_value) { return _Value; } else { - return static_cast<_Ty>(_STD forward<_Uty>(_Other)); + return static_cast>(_STD forward<_Uty>(_Other)); } } - template - _NODISCARD constexpr _Ty value_or(_Uty&& _Other) && noexcept( - is_nothrow_move_constructible_v<_Ty> && is_nothrow_convertible_v<_Uty, _Ty>) /* strengthened */ { - static_assert( - is_move_constructible_v<_Ty>, "is_move_constructible_v must be true. (N4950 [expected.object.obs]/20)"); - static_assert( - is_convertible_v<_Uty, _Ty>, "is_convertible_v must be true. (N4950 [expected.object.obs]/20)"); + template > + _NODISCARD constexpr remove_cv_t<_Ty> value_or(_Uty&& _Other) && noexcept( + is_nothrow_convertible_v<_Ty, remove_cv_t<_Ty>> + && is_nothrow_convertible_v<_Uty, remove_cv_t<_Ty>>) /* strengthened */ { + static_assert(is_convertible_v<_Ty, remove_cv_t<_Ty>>, + "is_convertible_v> must be true. " + "(N5001 [expected.object.obs]/20 as modified by LWG-3424)"); + static_assert(is_convertible_v<_Uty, remove_cv_t<_Ty>>, + "is_convertible_v> must be true. " + "(N5001 [expected.object.obs]/20 as modified by LWG-3424)"); if (_Has_value) { return _STD move(_Value); } else { - return static_cast<_Ty>(_STD forward<_Uty>(_Other)); + return static_cast>(_STD forward<_Uty>(_Other)); } } diff --git a/stl/inc/filesystem b/stl/inc/filesystem index 8a20d566326..34562e576cb 100644 --- a/stl/inc/filesystem +++ b/stl/inc/filesystem @@ -352,19 +352,12 @@ namespace filesystem { inline constexpr _Is_slash_oper _Is_slash{}; - template - _NODISCARD _Ty _Unaligned_load(const void* _Ptr) { // load a _Ty from _Ptr - static_assert(is_trivial_v<_Ty>, "Unaligned loads require trivial types"); - _Ty _Tmp; - _CSTD memcpy(&_Tmp, _Ptr, sizeof(_Tmp)); - return _Tmp; - } - _NODISCARD inline bool _Is_drive_prefix(const wchar_t* const _First) { // test if _First points to a prefix of the form X: // pre: _First points to at least 2 wchar_t instances // pre: Little endian - auto _Value = _Unaligned_load(_First); + unsigned int _Value; + _CSTD memcpy(&_Value, _First, sizeof(_Value)); // load from possibly unaligned address _Value &= 0xFFFF'FFDFu; // transform lowercase drive letters into uppercase ones _Value -= (static_cast(L':') << (sizeof(wchar_t) * CHAR_BIT)) | L'A'; return _Value < 26; diff --git a/stl/inc/flat_map b/stl/inc/flat_map index 9ce2dd5aa20..d19fa701afc 100644 --- a/stl/inc/flat_map +++ b/stl/inc/flat_map @@ -1293,47 +1293,43 @@ private: template _Compare = less> -flat_map(_KeyContainer, _MappedContainer, - _Compare = _Compare()) -> flat_map; +flat_map(_KeyContainer, _MappedContainer, _Compare = _Compare()) -> flat_map; template _Allocator> -flat_map(_KeyContainer, _MappedContainer, - _Allocator) -> flat_map, _KeyContainer, _MappedContainer>; +flat_map(_KeyContainer, _MappedContainer, _Allocator) -> flat_map, _KeyContainer, _MappedContainer>; template _Compare, _Usable_allocator_for<_KeyContainer, _MappedContainer> _Allocator> -flat_map(_KeyContainer, _MappedContainer, _Compare, - _Allocator) -> flat_map; +flat_map(_KeyContainer, _MappedContainer, _Compare, _Allocator) -> flat_map; template _Compare = less> -flat_map(sorted_unique_t, _KeyContainer, _MappedContainer, - _Compare = _Compare()) -> flat_map; +flat_map(sorted_unique_t, _KeyContainer, _MappedContainer, _Compare = _Compare()) + -> flat_map; template _Allocator> -flat_map(sorted_unique_t, _KeyContainer, _MappedContainer, - _Allocator) -> flat_map, _KeyContainer, _MappedContainer>; +flat_map(sorted_unique_t, _KeyContainer, _MappedContainer, _Allocator) -> flat_map, _KeyContainer, _MappedContainer>; template _Compare, _Usable_allocator_for<_KeyContainer, _MappedContainer> _Allocator> -flat_map(sorted_unique_t, _KeyContainer, _MappedContainer, _Compare, - _Allocator) -> flat_map; +flat_map(sorted_unique_t, _KeyContainer, _MappedContainer, _Compare, _Allocator) + -> flat_map; template >> -flat_map(_InputIterator, _InputIterator, - _Compare = _Compare()) -> flat_map<_Guide_key_t<_InputIterator>, _Guide_val_t<_InputIterator>, _Compare>; +flat_map(_InputIterator, _InputIterator, _Compare = _Compare()) + -> flat_map<_Guide_key_t<_InputIterator>, _Guide_val_t<_InputIterator>, _Compare>; template >> -flat_map(sorted_unique_t, _InputIterator, _InputIterator, - _Compare = _Compare()) -> flat_map<_Guide_key_t<_InputIterator>, _Guide_val_t<_InputIterator>, _Compare>; +flat_map(sorted_unique_t, _InputIterator, _InputIterator, _Compare = _Compare()) + -> flat_map<_Guide_key_t<_InputIterator>, _Guide_val_t<_InputIterator>, _Compare>; #ifdef __cpp_lib_byte template <_RANGES input_range _Rng, class _Compare = less<_Range_key_type<_Rng>>, class _Allocator = allocator> @@ -1343,29 +1339,26 @@ flat_map(from_range_t, _Rng&&, _Compare = _Compare(), _Allocator = _Allocator()) vector<_Range_mapped_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_mapped_type<_Rng>>>>; #else // ^^^ defined(__cpp_lib_byte) / !defined(__cpp_lib_byte) vvv template <_RANGES input_range _Rng, class _Compare = less<_Range_key_type<_Rng>>> -flat_map( - from_range_t, _Rng&&, _Compare = _Compare()) -> flat_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Compare, - vector<_Range_key_type<_Rng>>, vector<_Range_mapped_type<_Rng>>>; +flat_map(from_range_t, _Rng&&, _Compare = _Compare()) -> flat_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, + _Compare, vector<_Range_key_type<_Rng>>, vector<_Range_mapped_type<_Rng>>>; template <_RANGES input_range _Rng, class _Compare, class _Allocator> -flat_map(from_range_t, _Rng&&, _Compare, - _Allocator) -> flat_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Compare, - vector<_Range_key_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_key_type<_Rng>>>, - vector<_Range_mapped_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_mapped_type<_Rng>>>>; +flat_map(from_range_t, _Rng&&, _Compare, _Allocator) -> flat_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, + _Compare, vector<_Range_key_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_key_type<_Rng>>>, + vector<_Range_mapped_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_mapped_type<_Rng>>>>; #endif // ^^^ !defined(__cpp_lib_byte) ^^^ template <_RANGES input_range _Rng, class _Allocator> -flat_map(from_range_t, _Rng&&, - _Allocator) -> flat_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, less<_Range_key_type<_Rng>>, - vector<_Range_key_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_key_type<_Rng>>>, - vector<_Range_mapped_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_mapped_type<_Rng>>>>; +flat_map(from_range_t, _Rng&&, _Allocator) -> flat_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, + less<_Range_key_type<_Rng>>, vector<_Range_key_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_key_type<_Rng>>>, + vector<_Range_mapped_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_mapped_type<_Rng>>>>; template > flat_map(initializer_list>, _Compare = _Compare()) -> flat_map<_Key, _Mapped, _Compare>; template > -flat_map( - sorted_unique_t, initializer_list>, _Compare = _Compare()) -> flat_map<_Key, _Mapped, _Compare>; +flat_map(sorted_unique_t, initializer_list>, _Compare = _Compare()) + -> flat_map<_Key, _Mapped, _Compare>; // Specialization of uses_allocator template @@ -1442,40 +1435,39 @@ private: }; template > -flat_multimap(_KeyContainer, _MappedContainer, - _Compare = _Compare()) -> flat_multimap; +flat_multimap(_KeyContainer, _MappedContainer, _Compare = _Compare()) + -> flat_multimap; template -flat_multimap(_KeyContainer, _MappedContainer, - _Allocator) -> flat_multimap, _KeyContainer, _MappedContainer>; +flat_multimap(_KeyContainer, _MappedContainer, _Allocator) -> flat_multimap, _KeyContainer, _MappedContainer>; template -flat_multimap(_KeyContainer, _MappedContainer, _Compare, - _Allocator) -> flat_multimap; +flat_multimap(_KeyContainer, _MappedContainer, _Compare, _Allocator) + -> flat_multimap; template > -flat_multimap(sorted_equivalent_t, _KeyContainer, _MappedContainer, - _Compare = _Compare()) -> flat_multimap; +flat_multimap(sorted_equivalent_t, _KeyContainer, _MappedContainer, _Compare = _Compare()) + -> flat_multimap; template -flat_multimap(sorted_equivalent_t, _KeyContainer, _MappedContainer, - _Allocator) -> flat_multimap, _KeyContainer, _MappedContainer>; +flat_multimap(sorted_equivalent_t, _KeyContainer, _MappedContainer, _Allocator) + -> flat_multimap, _KeyContainer, _MappedContainer>; template -flat_multimap(sorted_equivalent_t, _KeyContainer, _MappedContainer, _Compare, - _Allocator) -> flat_multimap; +flat_multimap(sorted_equivalent_t, _KeyContainer, _MappedContainer, _Compare, _Allocator) + -> flat_multimap; template >> -flat_multimap(_InputIterator, _InputIterator, - _Compare = _Compare()) -> flat_multimap<_Guide_key_t<_InputIterator>, _Guide_val_t<_InputIterator>, _Compare>; +flat_multimap(_InputIterator, _InputIterator, _Compare = _Compare()) + -> flat_multimap<_Guide_key_t<_InputIterator>, _Guide_val_t<_InputIterator>, _Compare>; template >> -flat_multimap(sorted_equivalent_t, _InputIterator, _InputIterator, - _Compare = _Compare()) -> flat_multimap<_Guide_key_t<_InputIterator>, _Guide_val_t<_InputIterator>, _Compare>; +flat_multimap(sorted_equivalent_t, _InputIterator, _InputIterator, _Compare = _Compare()) + -> flat_multimap<_Guide_key_t<_InputIterator>, _Guide_val_t<_InputIterator>, _Compare>; #ifdef __cpp_lib_byte template <_RANGES input_range _Rng, class _Compare = less<_Range_key_type<_Rng>>, class _Allocator = allocator> @@ -1485,29 +1477,27 @@ flat_multimap(from_range_t, _Rng&&, _Compare = _Compare(), _Allocator = _Allocat vector<_Range_mapped_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_mapped_type<_Rng>>>>; #else // ^^^ defined(__cpp_lib_byte) / !defined(__cpp_lib_byte) vvv template <_RANGES input_range _Rng, class _Compare = less<_Range_key_type<_Rng>>> -flat_multimap(from_range_t, _Rng&&, - _Compare = _Compare()) -> flat_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Compare, - vector<_Range_key_type<_Rng>>, vector<_Range_mapped_type<_Rng>>>; +flat_multimap(from_range_t, _Rng&&, _Compare = _Compare()) -> flat_multimap<_Range_key_type<_Rng>, + _Range_mapped_type<_Rng>, _Compare, vector<_Range_key_type<_Rng>>, vector<_Range_mapped_type<_Rng>>>; template <_RANGES input_range _Rng, class _Compare, class _Allocator> -flat_multimap(from_range_t, _Rng&&, _Compare, - _Allocator) -> flat_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Compare, - vector<_Range_key_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_key_type<_Rng>>>, - vector<_Range_mapped_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_mapped_type<_Rng>>>>; +flat_multimap(from_range_t, _Rng&&, _Compare, _Allocator) + -> flat_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Compare, + vector<_Range_key_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_key_type<_Rng>>>, + vector<_Range_mapped_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_mapped_type<_Rng>>>>; #endif // ^^^ !defined(__cpp_lib_byte) ^^^ template <_RANGES input_range _Rng, class _Allocator> -flat_multimap(from_range_t, _Rng&&, - _Allocator) -> flat_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, less<_Range_key_type<_Rng>>, - vector<_Range_key_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_key_type<_Rng>>>, - vector<_Range_mapped_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_mapped_type<_Rng>>>>; +flat_multimap(from_range_t, _Rng&&, _Allocator) -> flat_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, + less<_Range_key_type<_Rng>>, vector<_Range_key_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_key_type<_Rng>>>, + vector<_Range_mapped_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_mapped_type<_Rng>>>>; template > flat_multimap(initializer_list>, _Compare = _Compare()) -> flat_multimap<_Key, _Mapped, _Compare>; template > -flat_multimap(sorted_equivalent_t, initializer_list>, - _Compare = _Compare()) -> flat_multimap<_Key, _Mapped, _Compare>; +flat_multimap(sorted_equivalent_t, initializer_list>, _Compare = _Compare()) + -> flat_multimap<_Key, _Mapped, _Compare>; // Specialization of uses_allocator template diff --git a/stl/inc/flat_set b/stl/inc/flat_set index fe3d087c00c..8e911ee6227 100644 --- a/stl/inc/flat_set +++ b/stl/inc/flat_set @@ -730,17 +730,17 @@ struct uses_allocator, _Alloc> template > flat_set(_Container, _Keylt = _Keylt()) -> flat_set; template -flat_set( - _Container, _Alloc) -> flat_set, _Container>; +flat_set(_Container, _Alloc) + -> flat_set, _Container>; template flat_set(_Container, _Keylt, _Alloc) -> flat_set; template > -flat_set( - sorted_unique_t, _Container, _Keylt = _Keylt()) -> flat_set; +flat_set(sorted_unique_t, _Container, _Keylt = _Keylt()) + -> flat_set; template -flat_set(sorted_unique_t, _Container, - _Alloc) -> flat_set, _Container>; +flat_set(sorted_unique_t, _Container, _Alloc) + -> flat_set, _Container>; template flat_set(sorted_unique_t, _Container, _Keylt, _Alloc) -> flat_set; @@ -750,13 +750,11 @@ template >> flat_set(sorted_unique_t, _Iter, _Iter, _Keylt = _Keylt()) -> flat_set, _Keylt>; template <_RANGES input_range _Range, class _Keylt = less<_RANGES range_value_t<_Range>>, class _Alloc = allocator<_RANGES range_value_t<_Range>>> -flat_set(from_range_t, _Range&&, _Keylt = _Keylt(), _Alloc = _Alloc()) - -> flat_set<_RANGES range_value_t<_Range>, _Keylt, - vector<_RANGES range_value_t<_Range>, _Rebind_alloc_t<_Alloc, _RANGES range_value_t<_Range>>>>; +flat_set(from_range_t, _Range&&, _Keylt = _Keylt(), _Alloc = _Alloc()) -> flat_set<_RANGES range_value_t<_Range>, + _Keylt, vector<_RANGES range_value_t<_Range>, _Rebind_alloc_t<_Alloc, _RANGES range_value_t<_Range>>>>; template <_RANGES input_range _Range, class _Alloc> -flat_set(from_range_t, _Range&&, - _Alloc) -> flat_set<_RANGES range_value_t<_Range>, less<_RANGES range_value_t<_Range>>, - vector<_RANGES range_value_t<_Range>, _Rebind_alloc_t<_Alloc, _RANGES range_value_t<_Range>>>>; +flat_set(from_range_t, _Range&&, _Alloc) -> flat_set<_RANGES range_value_t<_Range>, less<_RANGES range_value_t<_Range>>, + vector<_RANGES range_value_t<_Range>, _Rebind_alloc_t<_Alloc, _RANGES range_value_t<_Range>>>>; template > flat_set(initializer_list<_Kty>, _Keylt = _Keylt()) -> flat_set<_Kty, _Keylt>; template > @@ -766,35 +764,35 @@ flat_set(sorted_unique_t, initializer_list<_Kty>, _Keylt = _Keylt()) -> flat_set template > flat_multiset(_Container, _Keylt = _Keylt()) -> flat_multiset; template -flat_multiset(_Container, - _Alloc) -> flat_multiset, _Container>; +flat_multiset(_Container, _Alloc) + -> flat_multiset, _Container>; template flat_multiset(_Container, _Keylt, _Alloc) -> flat_multiset; template > -flat_multiset(sorted_equivalent_t, _Container, - _Keylt = _Keylt()) -> flat_multiset; +flat_multiset(sorted_equivalent_t, _Container, _Keylt = _Keylt()) + -> flat_multiset; template -flat_multiset(sorted_equivalent_t, _Container, - _Alloc) -> flat_multiset, _Container>; +flat_multiset(sorted_equivalent_t, _Container, _Alloc) + -> flat_multiset, _Container>; template -flat_multiset(sorted_equivalent_t, _Container, _Keylt, - _Alloc) -> flat_multiset; +flat_multiset(sorted_equivalent_t, _Container, _Keylt, _Alloc) + -> flat_multiset; template >> flat_multiset(_Iter, _Iter, _Keylt = _Keylt()) -> flat_multiset, iter_value_t<_Iter>, _Keylt>; template >> -flat_multiset(sorted_equivalent_t, _Iter, _Iter, - _Keylt = _Keylt()) -> flat_multiset, iter_value_t<_Iter>, _Keylt>; +flat_multiset(sorted_equivalent_t, _Iter, _Iter, _Keylt = _Keylt()) + -> flat_multiset, iter_value_t<_Iter>, _Keylt>; template <_RANGES input_range _Range, class _Keylt = less<_RANGES range_value_t<_Range>>, class _Alloc = allocator<_RANGES range_value_t<_Range>>> flat_multiset(from_range_t, _Range&&, _Keylt = _Keylt(), _Alloc = _Alloc()) -> flat_multiset<_RANGES range_value_t<_Range>, _Keylt, vector<_RANGES range_value_t<_Range>, _Rebind_alloc_t<_Alloc, _RANGES range_value_t<_Range>>>>; template <_RANGES input_range _Range, class _Alloc> -flat_multiset(from_range_t, _Range&&, - _Alloc) -> flat_multiset<_RANGES range_value_t<_Range>, less<_RANGES range_value_t<_Range>>, - vector<_RANGES range_value_t<_Range>, _Rebind_alloc_t<_Alloc, _RANGES range_value_t<_Range>>>>; +flat_multiset(from_range_t, _Range&&, _Alloc) + -> flat_multiset<_RANGES range_value_t<_Range>, less<_RANGES range_value_t<_Range>>, + vector<_RANGES range_value_t<_Range>, _Rebind_alloc_t<_Alloc, _RANGES range_value_t<_Range>>>>; template > flat_multiset(initializer_list<_Kty>, _Keylt = _Keylt()) -> flat_multiset<_Kty, _Keylt>; template > diff --git a/stl/inc/format b/stl/inc/format index 6026f34202d..53b960dbdd6 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -3288,9 +3288,11 @@ void _Range_formatter_format_as_string(_Range&& _Rng, _FormatContext& _Ctx, cons if constexpr (_RANGES contiguous_range<_Range>) { const auto _Size = _STD _To_unsigned_like(_RANGES distance(_Rng)); - if (!_STD in_range(_Size)) [[unlikely]] { - _Throw_format_error("Formatted range is too long."); +#ifdef _DEBUG + if constexpr (sizeof(_Size) > sizeof(size_t)) { + _STL_VERIFY(_Size <= size_t{PTRDIFF_MAX}, "contiguous range has impossible size."); } +#endif // defined(_DEBUG) formatter, _CharT> _String_view_formatter; if (_Debug) { diff --git a/stl/inc/functional b/stl/inc/functional index aa5519259c9..7ed26be7e7c 100644 --- a/stl/inc/functional +++ b/stl/inc/functional @@ -580,7 +580,7 @@ public: }; _EXPORT_STD template -_NODISCARD _CONSTEXPR20 _Mem_fn<_Rx _Ty::*> mem_fn(_Rx _Ty::*_Pm) noexcept { +_NODISCARD _CONSTEXPR20 _Mem_fn<_Rx _Ty::*> mem_fn(_Rx _Ty::* _Pm) noexcept { return _Mem_fn<_Rx _Ty::*>(_Pm); } @@ -2341,9 +2341,8 @@ _NODISCARD constexpr auto bind_front(_Fx&& _Func, _Types&&... _Args) { template constexpr auto _Call_back_binder(index_sequence<_Ix...>, _Cv_FD&& _Obj, _Cv_tuple_TiD&& _Tpl, _Unbound&&... _Unbargs) noexcept(noexcept(_STD invoke(_STD forward<_Cv_FD>(_Obj), _STD forward<_Unbound>(_Unbargs)..., - _STD get<_Ix>(_STD forward<_Cv_tuple_TiD>(_Tpl))...))) - -> decltype(_STD invoke(_STD forward<_Cv_FD>(_Obj), _STD forward<_Unbound>(_Unbargs)..., - _STD get<_Ix>(_STD forward<_Cv_tuple_TiD>(_Tpl))...)) { + _STD get<_Ix>(_STD forward<_Cv_tuple_TiD>(_Tpl))...))) -> decltype(_STD invoke(_STD forward<_Cv_FD>(_Obj), + _STD forward<_Unbound>(_Unbargs)..., _STD get<_Ix>(_STD forward<_Cv_tuple_TiD>(_Tpl))...)) { return _STD invoke(_STD forward<_Cv_FD>(_Obj), _STD forward<_Unbound>(_Unbargs)..., _STD get<_Ix>(_STD forward<_Cv_tuple_TiD>(_Tpl))...); } diff --git a/stl/inc/generator b/stl/inc/generator index 8e5d94619d9..524b9a22687 100644 --- a/stl/inc/generator +++ b/stl/inc/generator @@ -110,16 +110,18 @@ namespace _Gen_detail { } template - requires convertible_to _NODISCARD_RAW_PTR_ALLOC static void* operator new( const size_t _Size, allocator_arg_t, const _Alloc2& _Al, const _Args&...) { + static_assert(convertible_to, + "Allocator argument must be convertible to the allocator type (N5001 [coro.generator.promise]/18)"); return _Allocate(static_cast<_Alloc>(static_cast<_Proto_allocator>(_Al)), _Size); } template - requires convertible_to _NODISCARD_RAW_PTR_ALLOC static void* operator new( const size_t _Size, const _This&, allocator_arg_t, const _Alloc2& _Al, const _Args&...) { + static_assert(convertible_to, + "Allocator argument must be convertible to the allocator type (N5001 [coro.generator.promise]/18)"); return _Allocate(static_cast<_Alloc>(static_cast<_Proto_allocator>(_Al)), _Size); } @@ -287,11 +289,10 @@ namespace _Gen_detail { template <_RANGES input_range _Rng, class _Alloc> requires convertible_to<_RANGES range_reference_t<_Rng>, _Yielded> _NODISCARD auto yield_value(_RANGES elements_of<_Rng, _Alloc> _Elem) { - using _Vty = _RANGES range_value_t<_Rng>; - using _Nested_awaitable = _Nested_awaitable_provider<_Yielded, _Vty, _Alloc>::_Awaitable; + using _Nested_awaitable = _Nested_awaitable_provider<_Yielded, void, _Alloc>::_Awaitable; auto _Lambda = [](allocator_arg_t, _Alloc, _RANGES iterator_t<_Rng> _It, - const _RANGES sentinel_t<_Rng> _Se) -> generator<_Yielded, _Vty, _Alloc> { + const _RANGES sentinel_t<_Rng> _Se) -> generator<_Yielded, void, _Alloc> { for (; _It != _Se; ++_It) { co_yield static_cast<_Yielded>(*_It); } diff --git a/stl/inc/hash_map b/stl/inc/hash_map index b204ecba06f..e43b4099a76 100644 --- a/stl/inc/hash_map +++ b/stl/inc/hash_map @@ -54,14 +54,10 @@ namespace stdext { template using _In_place_key_extractor = _STD _In_place_key_extract_map<_Kty, _Args...>; - template - using _Deduce_key = const _Kty&; - using key_equal = _Tr; - -#if _HAS_CXX20 && defined(__EDG__) // TRANSITION, DevCom-10678753 - template - static constexpr bool _Supports_transparency = false; -#endif // ^^^ workaround ^^^ + + using key_equal = _Tr; + + static constexpr bool _Has_transparent_overloads = false; _Hmap_traits() = default; diff --git a/stl/inc/hash_set b/stl/inc/hash_set index 914a09c5586..676680998ed 100644 --- a/stl/inc/hash_set +++ b/stl/inc/hash_set @@ -49,14 +49,10 @@ namespace stdext { template using _In_place_key_extractor = _STD _In_place_key_extract_set<_Kty, _Args...>; - template - using _Deduce_key = const _Kty&; - using key_equal = _Tr; - -#if _HAS_CXX20 && defined(__EDG__) // TRANSITION, DevCom-10678753 - template - static constexpr bool _Supports_transparency = false; -#endif // ^^^ workaround ^^^ + + using key_equal = _Tr; + + static constexpr bool _Has_transparent_overloads = false; _Hset_traits() = default; diff --git a/stl/inc/map b/stl/inc/map index 4e601e3a0b4..1e7c30bc404 100644 --- a/stl/inc/map +++ b/stl/inc/map @@ -387,12 +387,12 @@ map(initializer_list>, _Alloc) -> map<_Kty, _Ty, less<_Kty>, _Al template <_RANGES input_range _Rng, class _Pr = less<_Range_key_type<_Rng>>, _Allocator_for_container _Alloc = allocator<_Range_to_alloc_type<_Rng>>> requires (!_Allocator_for_container<_Pr>) -map(from_range_t, _Rng&&, _Pr = _Pr(), - _Alloc = _Alloc()) -> map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Pr, _Alloc>; +map(from_range_t, _Rng&&, _Pr = _Pr(), _Alloc = _Alloc()) + -> map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Pr, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -map(from_range_t, _Rng&&, - _Alloc) -> map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, less<_Range_key_type<_Rng>>, _Alloc>; +map(from_range_t, _Rng&&, _Alloc) + -> map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, less<_Range_key_type<_Rng>>, _Alloc>; #endif // _HAS_CXX23 #endif // _HAS_CXX17 @@ -601,8 +601,8 @@ public: #if _HAS_CXX17 template >, class _Alloc = allocator<_Guide_pair_t<_Iter>>, enable_if_t, negation<_Is_allocator<_Pr>>, _Is_allocator<_Alloc>>, int> = 0> -multimap( - _Iter, _Iter, _Pr = _Pr(), _Alloc = _Alloc()) -> multimap<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, _Pr, _Alloc>; +multimap(_Iter, _Iter, _Pr = _Pr(), _Alloc = _Alloc()) + -> multimap<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, _Pr, _Alloc>; template , class _Alloc = allocator>, enable_if_t>, _Is_allocator<_Alloc>>, int> = 0> @@ -618,12 +618,12 @@ multimap(initializer_list>, _Alloc) -> multimap<_Kty, _Ty, less< template <_RANGES input_range _Rng, class _Pr = less<_Range_key_type<_Rng>>, _Allocator_for_container _Alloc = allocator<_Range_to_alloc_type<_Rng>>> requires (!_Allocator_for_container<_Pr>) -multimap(from_range_t, _Rng&&, _Pr = _Pr(), - _Alloc = _Alloc()) -> multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Pr, _Alloc>; +multimap(from_range_t, _Rng&&, _Pr = _Pr(), _Alloc = _Alloc()) + -> multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Pr, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -multimap(from_range_t, _Rng&&, - _Alloc) -> multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, less<_Range_key_type<_Rng>>, _Alloc>; +multimap(from_range_t, _Rng&&, _Alloc) + -> multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, less<_Range_key_type<_Rng>>, _Alloc>; #endif // _HAS_CXX23 #endif // _HAS_CXX17 diff --git a/stl/inc/mdspan b/stl/inc/mdspan index 3bb2292c5e2..99b6b7333bf 100644 --- a/stl/inc/mdspan +++ b/stl/inc/mdspan @@ -1463,17 +1463,17 @@ template mdspan(_ElementType*, const array<_OtherIndexType, _Nx>&) -> mdspan<_ElementType, dextents>; template -mdspan(_ElementType*, - const extents<_IndexType, _ExtentsPack...>&) -> mdspan<_ElementType, extents<_IndexType, _ExtentsPack...>>; +mdspan(_ElementType*, const extents<_IndexType, _ExtentsPack...>&) + -> mdspan<_ElementType, extents<_IndexType, _ExtentsPack...>>; template mdspan(_ElementType*, const _MappingType&) -> mdspan<_ElementType, typename _MappingType::extents_type, typename _MappingType::layout_type>; template -mdspan(const typename _AccessorType::data_handle_type&, const _MappingType&, - const _AccessorType&) -> mdspan; +mdspan(const typename _AccessorType::data_handle_type&, const _MappingType&, const _AccessorType&) + -> mdspan; _STD_END diff --git a/stl/inc/memory b/stl/inc/memory index 864f44f90af..49d0e0af838 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -2246,7 +2246,8 @@ struct _NODISCARD _Reverse_destroy_multidimensional_n_guard { template void _Uninitialized_copy_multidimensional(const _Ty (&_In)[_Size], _Ty (&_Out)[_Size]) { - if constexpr (is_trivial_v<_Ty>) { + using _Item = remove_all_extents_t<_Ty>; + if constexpr (conjunction_v, is_trivially_destructible<_Item>>) { _STD _Copy_memmove_n(_In, _Size, _Out); } else if constexpr (is_array_v<_Ty>) { _Reverse_destroy_multidimensional_n_guard<_Ty> _Guard{_Out, 0}; @@ -2610,7 +2611,8 @@ struct _NODISCARD _Reverse_destroy_multidimensional_n_al_guard { template void _Uninitialized_copy_multidimensional_al(const _Ty (&_In)[_Size], _Ty (&_Out)[_Size], _Alloc& _Al) { using _Item = remove_all_extents_t<_Ty>; - if constexpr (conjunction_v, _Uses_default_construct<_Alloc, _Item*, const _Item&>>) { + if constexpr (conjunction_v, is_trivially_destructible<_Item>, + _Uses_default_construct<_Alloc, _Item*, const _Item&>>) { _STD _Copy_memmove_n(_In, _Size, _Out); } else if constexpr (is_array_v<_Ty>) { _Reverse_destroy_multidimensional_n_al_guard<_Ty, _Alloc> _Guard{_Out, 0, _Al}; @@ -3329,9 +3331,17 @@ template using _Unique_ptr_enable_default_t = enable_if_t>, is_default_constructible<_Dx2>>, int>; +template +constexpr bool _Can_form_pointer = false; +template +constexpr bool _Can_form_pointer<_Ty, void_t<_Ty*>> = true; + _EXPORT_STD template */> class unique_ptr { // non-copyable pointer to an object public: + static_assert(_Can_form_pointer<_Ty>, + "unique_ptr requires T* to be a valid type (N5001 [unique.ptr.single.general]/1)."); + using pointer = typename _Get_deleter_pointer_type<_Ty, remove_reference_t<_Dx>>::type; using element_type = _Ty; using deleter_type = _Dx; diff --git a/stl/inc/optional b/stl/inc/optional index 2aae7cd4dd3..28e41c46abf 100644 --- a/stl/inc/optional +++ b/stl/inc/optional @@ -252,7 +252,7 @@ public: negation, bool>, _Is_specialization<_Remove_cvref_t<_Ty2>, optional>>>, is_constructible<_Ty, _Ty2>>>; - template ::value, int> = 0> + template , enable_if_t<_AllowDirectConversion<_Ty2>::value, int> = 0> constexpr explicit(!is_convertible_v<_Ty2, _Ty>) optional(_Ty2&& _Right) noexcept(is_nothrow_constructible_v<_Ty, _Ty2>) // strengthened : _Mybase(in_place, _STD forward<_Ty2>(_Right)) {} @@ -288,10 +288,11 @@ public: return *this; } - template >>, - negation, is_same<_Ty, decay_t<_Ty2>>>>, - is_constructible<_Ty, _Ty2>, is_assignable<_Ty&, _Ty2>>, - int> = 0> + template , + enable_if_t>>, + negation, is_same<_Ty, decay_t<_Ty2>>>>, is_constructible<_Ty, _Ty2>, + is_assignable<_Ty&, _Ty2>>, + int> = 0> _CONSTEXPR20 optional& operator=(_Ty2&& _Right) noexcept(is_nothrow_assignable_v<_Ty&, _Ty2> && is_nothrow_constructible_v<_Ty, _Ty2>) /* strengthened */ { this->_Assign(_STD forward<_Ty2>(_Right)); @@ -425,13 +426,14 @@ public: return _STD move(this->_Value); } - template + template > _NODISCARD constexpr remove_cv_t<_Ty> value_or(_Ty2&& _Right) const& { static_assert(is_convertible_v>, "The const overload of optional::value_or requires const T& to be convertible to remove_cv_t " "(N4950 [optional.observe]/15 as modified by LWG-3424)."); - static_assert(is_convertible_v<_Ty2, _Ty>, - "optional::value_or(U) requires U to be convertible to T (N4950 [optional.observe]/15)."); + static_assert(is_convertible_v<_Ty2, remove_cv_t<_Ty>>, + "optional::value_or(U) requires U to be convertible to remove_cv_t " + "(N4950 [optional.observe]/15 as modified by LWG-3424)."); if (this->_Has_value) { return static_cast(this->_Value); @@ -439,13 +441,14 @@ public: return static_cast>(_STD forward<_Ty2>(_Right)); } - template + template > _NODISCARD constexpr remove_cv_t<_Ty> value_or(_Ty2&& _Right) && { static_assert(is_convertible_v<_Ty, remove_cv_t<_Ty>>, "The rvalue overload of optional::value_or requires T to be convertible to remove_cv_t " "(N4950 [optional.observe]/17 as modified by LWG-3424)."); - static_assert(is_convertible_v<_Ty2, _Ty>, - "optional::value_or(U) requires U to be convertible to T (N4950 [optional.observe]/17)."); + static_assert(is_convertible_v<_Ty2, remove_cv_t<_Ty>>, + "optional::value_or(U) requires U to be convertible to remove_cv_t " + "(N4950 [optional.observe]/17 as modified by LWG-3424)."); if (this->_Has_value) { return static_cast<_Ty&&>(this->_Value); diff --git a/stl/inc/queue b/stl/inc/queue index b73b8cd1fa7..315033ad851 100644 --- a/stl/inc/queue +++ b/stl/inc/queue @@ -174,8 +174,8 @@ template <_Iterator_for_container _InIt, _Allocator_for_container _Alloc = alloc queue(_InIt, _InIt, _Alloc = _Alloc()) -> queue<_Iter_value_t<_InIt>, deque<_Iter_value_t<_InIt>, _Alloc>>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc = allocator<_RANGES range_value_t<_Rng>>> -queue(from_range_t, _Rng&&, - _Alloc = _Alloc()) -> queue<_RANGES range_value_t<_Rng>, deque<_RANGES range_value_t<_Rng>, _Alloc>>; +queue(from_range_t, _Rng&&, _Alloc = _Alloc()) + -> queue<_RANGES range_value_t<_Rng>, deque<_RANGES range_value_t<_Rng>, _Alloc>>; #endif // _HAS_CXX23 _EXPORT_STD template @@ -450,8 +450,8 @@ priority_queue(_Pr, _Container) -> priority_queue>, class _Container = vector<_Iter_value_t<_Iter>>, enable_if_t, negation<_Is_allocator<_Pr>>, negation<_Is_allocator<_Container>>>, int> = 0> -priority_queue( - _Iter, _Iter, _Pr = _Pr(), _Container = _Container()) -> priority_queue<_Iter_value_t<_Iter>, _Container, _Pr>; +priority_queue(_Iter, _Iter, _Pr = _Pr(), _Container = _Container()) + -> priority_queue<_Iter_value_t<_Iter>, _Container, _Pr>; template >, negation<_Is_allocator<_Container>>, @@ -469,23 +469,23 @@ priority_queue(_Iter, _Iter, _Compare, _Alloc) -> priority_queue<_Iter_value_t<_ template , uses_allocator<_Container, _Alloc>>, int> = 0> -priority_queue(_Iter, _Iter, _Compare, _Container, - _Alloc) -> priority_queue; +priority_queue(_Iter, _Iter, _Compare, _Container, _Alloc) + -> priority_queue; #if _HAS_CXX23 template <_RANGES input_range _Rng, class _Pr = less<_RANGES range_value_t<_Rng>>, enable_if_t::value, int> = 0> -priority_queue(from_range_t, _Rng&&, - _Pr = _Pr()) -> priority_queue<_RANGES range_value_t<_Rng>, vector<_RANGES range_value_t<_Rng>>, _Pr>; +priority_queue(from_range_t, _Rng&&, _Pr = _Pr()) + -> priority_queue<_RANGES range_value_t<_Rng>, vector<_RANGES range_value_t<_Rng>>, _Pr>; template <_RANGES input_range _Rng, class _Pr, class _Alloc, enable_if_t>, _Is_allocator<_Alloc>>, int> = 0> -priority_queue(from_range_t, _Rng&&, _Pr, - _Alloc) -> priority_queue<_RANGES range_value_t<_Rng>, vector<_RANGES range_value_t<_Rng>, _Alloc>, _Pr>; +priority_queue(from_range_t, _Rng&&, _Pr, _Alloc) + -> priority_queue<_RANGES range_value_t<_Rng>, vector<_RANGES range_value_t<_Rng>, _Alloc>, _Pr>; template <_RANGES input_range _Rng, class _Alloc, enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> -priority_queue(from_range_t, _Rng&&, - _Alloc) -> priority_queue<_RANGES range_value_t<_Rng>, vector<_RANGES range_value_t<_Rng>, _Alloc>>; +priority_queue(from_range_t, _Rng&&, _Alloc) + -> priority_queue<_RANGES range_value_t<_Rng>, vector<_RANGES range_value_t<_Rng>, _Alloc>>; #endif // _HAS_CXX23 #endif // _HAS_CXX17 diff --git a/stl/inc/ranges b/stl/inc/ranges index 38289d7320a..53da3d6daa2 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -1025,8 +1025,8 @@ namespace ranges { }; template - requires (!_Integer_like<_Wi> || !_Integer_like<_Bo> - || (_Signed_integer_like<_Wi> == _Signed_integer_like<_Bo>) ) + requires ( + !_Integer_like<_Wi> || !_Integer_like<_Bo> || (_Signed_integer_like<_Wi> == _Signed_integer_like<_Bo>) ) iota_view(_Wi, _Bo) -> iota_view<_Wi, _Bo>; template @@ -3989,8 +3989,8 @@ namespace ranges { lazy_split_view(_Rng&&, _Pat&&) -> lazy_split_view, views::all_t<_Pat>>; template - lazy_split_view( - _Rng&&, range_value_t<_Rng>) -> lazy_split_view, single_view>>; + lazy_split_view(_Rng&&, range_value_t<_Rng>) + -> lazy_split_view, single_view>>; #if _HAS_CXX23 template @@ -4216,12 +4216,11 @@ namespace ranges { using _Decayed = decay_t<_It>; _STL_INTERNAL_STATIC_ASSERT(input_or_output_iterator<_Decayed>); if constexpr (contiguous_iterator<_Decayed>) { - return {_St::_Span, - noexcept(span(_STD to_address(_STD declval<_It>()), iter_difference_t<_Decayed>{}))}; + return {_St::_Span, true}; } else if constexpr (random_access_iterator<_Decayed>) { return {_St::_Subrange, noexcept(subrange(_STD declval<_It>(), _STD declval<_It>() + iter_difference_t<_Decayed>{}))}; - } else if constexpr (constructible_from<_Decayed, _It>) { + } else if constexpr (is_convertible_v<_It, _Decayed>) { return {_St::_Subrange_counted, noexcept(subrange( counted_iterator(_STD declval<_It>(), iter_difference_t<_Decayed>{}), default_sentinel))}; @@ -7158,13 +7157,9 @@ namespace ranges { private: friend zip_view; -#if defined(__clang__) && __clang_major__ <= 18 // TRANSITION, Clang 19 (was thought to be LLVM-61763) - public: -#else // ^^^ workaround / no workaround vvv template requires _Zip_transform_constraints<_Func, _OtherViews...> friend class zip_transform_view; -#endif // ^^^ no workaround ^^^ using _My_tuple = tuple>...>; @@ -7983,13 +7978,9 @@ namespace ranges { private: friend adjacent_view; -#if defined(__clang__) && __clang_major__ <= 18 // TRANSITION, Clang 19 (was thought to be LLVM-61763) - public: -#else // ^^^ workaround / no workaround vvv template requires _Adjacent_transform_constraints<_Vw2, _Fn, _Nx2> friend class adjacent_transform_view; -#endif // ^^^ no workaround ^^^ using _Base = _Maybe_const<_Const, _Vw>; using _Base_iterator = iterator_t<_Base>; diff --git a/stl/inc/regex b/stl/inc/regex index b5fa6cae395..5491b129ed0 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -79,6 +79,8 @@ enum _Meta_type : int { // meta character representations for parser _Meta_nl = '\n', _Meta_cr = '\r', _Meta_bsp = '\b', + _Meta_ls = L'\u2028', + _Meta_ps = L'\u2029', _Meta_chr = 0, _Esc_bsl = '\\', @@ -149,7 +151,7 @@ namespace regex_constants { error_badrepeat, error_complexity, error_stack, - error_parse, + _Error_parse, // TRANSITION, was error_parse, keeping behavior error_syntax }; } // namespace regex_constants @@ -293,8 +295,7 @@ public: } _Elem translate(_Elem _Ch) const { // provide locale-sensitive mapping - string_type _Res = _Getcoll()->transform(_STD addressof(_Ch), _STD addressof(_Ch) + 1); - return _Res.size() == 1 ? _Res[0] : _Ch; + return _Ch; } _Elem translate_nocase(_Elem _Ch) const { // provide case-insensitive mapping @@ -333,8 +334,10 @@ public: template char_class_type lookup_classname(_Iter _First, _Iter _Last, bool _Icase = false) const { // map [_First, _Last) to character class mask value -#define _REGEX_CHAR_CLASS_NAME(n, c) \ - { n, L##n, static_cast(_STD size(n) - 1), c } +#define _REGEX_CHAR_CLASS_NAME(n, c) \ + { \ + n, L##n, static_cast(_STD size(n) - 1), c \ + } static constexpr _Cl_names _Names[] = { // map class names to numeric constants _REGEX_CHAR_CLASS_NAME("alnum", _Ch_alnum), @@ -464,12 +467,12 @@ _EXPORT_STD class _NODISCARD regex_error : public runtime_error { // type of all public: explicit regex_error(regex_constants::error_type _Ex) : runtime_error(_Stringify(_Ex)), _Err(_Ex) {} - _NODISCARD regex_constants::error_type code() const { + _NODISCARD regex_constants::error_type code() const noexcept /* strengthened */ { return _Err; } private: - static const char* _Stringify(regex_constants::error_type _Ex) { // map error code to string + static const char* _Stringify(regex_constants::error_type _Ex) noexcept { // map error code to string switch (_Ex) { // select known error_type message case regex_constants::error_collate: return "regex_error(error_collate): The expression " @@ -515,7 +518,7 @@ private: return "regex_error(error_stack): There was insufficient " "memory to determine whether the regular expression " "could match the specified character sequence."; - case regex_constants::error_parse: + case regex_constants::_Error_parse: // TRANSITION, keeping behavior return "regex_error(error_parse)"; case regex_constants::error_syntax: return "regex_error(error_syntax)"; @@ -1187,15 +1190,12 @@ _NODISCARD bool operator!=(const match_results<_BidIt, _Alloc>& _Left, const mat } #endif // !_HAS_CXX20 -_INLINE_VAR constexpr unsigned int _BRE_MAX_GRP = 9U; - _INLINE_VAR constexpr unsigned int _Bmp_max = 256U; // must fit in an unsigned int _INLINE_VAR constexpr unsigned int _Bmp_shift = 3U; _INLINE_VAR constexpr unsigned int _Bmp_chrs = 1U << _Bmp_shift; // # of bits to be stored in each char _INLINE_VAR constexpr unsigned int _Bmp_mask = _Bmp_chrs - 1U; _INLINE_VAR constexpr unsigned int _Bmp_size = (_Bmp_max + _Bmp_chrs - 1U) / _Bmp_chrs; -_INLINE_VAR constexpr unsigned int _Buf_incr = 16U; _INLINE_VAR constexpr unsigned int _ARRAY_THRESHOLD = 4U; enum _Node_flags : int { // flags for nfa nodes with special properties @@ -1257,9 +1257,9 @@ struct _Buf { // character buffer return _Chrs; } - void _Insert(_Elem _Ch) { // append _Ch + void _Insert2(_Elem _Ch) { // append _Ch if (_Sz <= _Nchrs) { - _Expand(_Nchrs + _Buf_incr); + _Expand2(1U); } _Chrs[_Nchrs++] = _Ch; @@ -1270,17 +1270,43 @@ struct _Buf { // character buffer } template - void _Insert(_FwdIt _First, _FwdIt _Last) { // append multiple characters + void _Insert2(_FwdIt _First, _FwdIt _Last) { // append multiple characters while (_First != _Last) { - _Insert(*_First++); + _Insert2(*_First++); } } private: - void _Expand(unsigned int _Len) { // expand buffer to hold _Len characters - _Elem* _Tmp = static_cast<_Elem*>(_CSTD realloc(_Chrs, _Get_size_of_n(_Len))); + unsigned int _Calculate_expansion(unsigned int _Increase) const { + constexpr size_t _Max_elems = static_cast(-1) / sizeof(_Elem); + constexpr unsigned int _Max_uint = static_cast(-1); + constexpr unsigned int _Max = _Max_elems < _Max_uint ? static_cast(_Max_elems) : _Max_uint; + + constexpr unsigned int _Buf_incr = 16U; + + if (_Increase < _Buf_incr) { + _Increase = _Buf_incr; + } + + if (_Increase < (_Sz >> 1)) { + _Increase = _Sz >> 1; + } + + if (_Max <= _Increase || _Max - _Increase <= _Sz) { + return _Max; + } + + return _Sz + _Increase; + } + + void _Expand2(const unsigned int _Min_increase) { // expand buffer by at least _Min_increase + const unsigned int _Len = _Calculate_expansion(_Min_increase); + if (_Len - _Sz < _Min_increase) { + _Xregex_error(regex_constants::error_space); + } + _Elem* _Tmp = static_cast<_Elem*>(_CSTD realloc(_Chrs, sizeof(_Elem) * static_cast(_Len))); if (!_Tmp) { - _Xbad_alloc(); + _Xregex_error(regex_constants::error_space); } _Chrs = _Tmp; @@ -1499,8 +1525,8 @@ public: void _Add_char(_Elem _Ch); void _Add_class(); void _Add_char_to_class(_Elem _Ch); - void _Add_range(_Elem _Ex0, _Elem _Ex1); - void _Add_named_class(_Regex_traits_base::char_class_type, bool = false); + void _Add_range2(_Elem, _Elem); + void _Add_named_class(typename _RxTraits::char_class_type, bool); void _Add_equiv(_FwdIt, _FwdIt, _Difft); void _Add_coll(_FwdIt, _FwdIt, _Difft); _Node_base* _Begin_group(); @@ -1524,7 +1550,7 @@ private: bool _Beg_expr(_Node_base*) const; void _Add_char_to_bitmap(_Elem _Ch); void _Add_char_to_array(_Elem _Ch); - void _Add_elts(_Node_class<_Elem, _RxTraits>*, _Regex_traits_base::char_class_type, bool); + void _Add_elts(_Node_class<_Elem, _RxTraits>*, typename _RxTraits::char_class_type, bool); void _Char_to_elts(_FwdIt, _FwdIt, _Difft, _Sequence<_Elem>**); _Root_node* _Root; @@ -1705,7 +1731,7 @@ private: // parsing int _Do_digits(int _Base, int _Count, regex_constants::error_type _Error_type); - bool _DecimalDigits(regex_constants::error_type _Error_type); + bool _DecimalDigits2(regex_constants::error_type _Error_type, int _Count = INT_MAX); void _HexDigits(int); bool _OctalDigits(); void _Do_ex_class(_Meta_type); @@ -1820,12 +1846,10 @@ public: } basic_regex(_In_reads_(_Count) const _Elem* _Ptr, size_t _Count, flag_type _Flags = regex_constants::ECMAScript) { - if (_Ptr) { - _Reset(_Ptr, _Ptr + _Count, _Flags); - return; - } - - _Xregex_error(regex_constants::error_parse); +#if _ITERATOR_DEBUG_LEVEL != 0 + _STL_VERIFY(_Ptr != nullptr || _Count == 0, "constructing basic_regex from an invalid range"); +#endif // ^^^ _ITERATOR_DEBUG_LEVEL != 0 ^^^ + _Reset(_Ptr, _Ptr + _Count, _Flags); } template @@ -2835,7 +2859,7 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_char(_Elem _Ch) { // append charac } _Node_str<_Elem>* _Node = static_cast<_Node_str<_Elem>*>(_Current); - _Node->_Data._Insert(_Ch); + _Node->_Data._Insert2(_Ch); } template @@ -2869,7 +2893,7 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_char_to_array(_Elem _Ch) { // appe _Node->_Large = new _Buf<_Elem>; } - _Node->_Large->_Insert(_Ch); + _Node->_Large->_Insert2(_Ch); } template @@ -2882,19 +2906,12 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_char_to_class(_Elem _Ch) { // add } template -void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_range(_Elem _Arg0, _Elem _Arg1) { +void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_range2(const _Elem _Arg0, const _Elem _Arg1) { // add character range to set - unsigned int _Ex0; - unsigned int _Ex1; - if (_Flags & regex_constants::icase) { // change to lowercase range - _Ex0 = static_cast(_Traits.translate_nocase(_Arg0)); - _Ex1 = static_cast(_Traits.translate_nocase(_Arg1)); - } else { - _Ex0 = static_cast(_Arg0); - _Ex1 = static_cast(_Arg1); - } - + unsigned int _Ex0 = static_cast(_Arg0); + const unsigned int _Ex1 = static_cast(_Arg1); _Node_class<_Elem, _RxTraits>* _Node = static_cast<_Node_class<_Elem, _RxTraits>*>(_Current); + for (; _Ex0 <= _Ex1 && _Ex1 < _Get_bmax(); ++_Ex0) { // set a bit if (!_Node->_Small) { _Node->_Small = new _Bitmap; @@ -2912,15 +2929,15 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_range(_Elem _Arg0, _Elem _Arg1) { _Node->_Ranges = new _Buf<_Elem>; } - _Node->_Ranges->_Insert(static_cast<_Elem>(_Ex0)); - _Node->_Ranges->_Insert(static_cast<_Elem>(_Ex1)); + _Node->_Ranges->_Insert2(static_cast<_Elem>(_Ex0)); + _Node->_Ranges->_Insert2(_Arg1); } } } template void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_elts( - _Node_class<_Elem, _RxTraits>* _Node, _Regex_traits_base::char_class_type _Cl, bool _Negate) { + _Node_class<_Elem, _RxTraits>* _Node, typename _RxTraits::char_class_type _Cl, bool _Negate) { // add characters in named class to set for (unsigned int _Ch = 0; _Ch < _Bmp_max; ++_Ch) { // add elements or their inverse bool _Matches = _Traits.isctype(static_cast<_Elem>(_Ch), _Cl); @@ -2935,12 +2952,12 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_elts( } template -void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_named_class(typename _Regex_traits_base::char_class_type _Cl, +void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_named_class(typename _RxTraits::char_class_type _Cl, bool _Negate) { // add contents of named class to bracket expression _Node_class<_Elem, _RxTraits>* _Node = static_cast<_Node_class<_Elem, _RxTraits>*>(_Current); _Add_elts(_Node, _Cl, _Negate); - if (_Bmp_max < static_cast(_STD _Max_limit<_Elem>())) { - _Node->_Classes = static_cast<_Regex_traits_base::char_class_type>(_Node->_Classes | _Cl); + if (_Bmp_max <= _STD _Max_limit() && !_Negate) { + _Node->_Classes = static_cast(_Node->_Classes | _Cl); } } @@ -2957,7 +2974,7 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Char_to_elts(_FwdIt _First, _FwdIt _La *_Cur = new _Sequence<_Elem>(static_cast(_Diff)); (*_Cur)->_Next = _Node; } - (*_Cur)->_Data._Insert(_First, _Last); + (*_Cur)->_Data._Insert2(_First, _Last); } template @@ -3507,10 +3524,23 @@ bool _Matcher<_BidIt, _Elem, _RxTraits, _It>::_Match_pat(_Node_base* _Nx) { // c break; case _N_dot: - if (_Tgt_state._Cur == _End || *_Tgt_state._Cur == _Meta_nl || *_Tgt_state._Cur == _Meta_cr) { + if (_Tgt_state._Cur == _End) { _Failed = true; } else { - ++_Tgt_state._Cur; + const _Elem _Ch = *_Tgt_state._Cur; + if (_Sflags + & (regex_constants::basic | regex_constants::extended | regex_constants::grep + | regex_constants::egrep | regex_constants::awk)) { + if (_Ch == _Elem()) { + _Failed = true; + } + } else if (_Ch == _Meta_nl || _Ch == _Meta_cr || _Ch == _Meta_ls || _Ch == _Meta_ps) { // ECMAScript + _Failed = true; + } + + if (!_Failed) { + ++_Tgt_state._Cur; + } } break; @@ -3652,7 +3682,11 @@ bool _Matcher<_BidIt, _Elem, _RxTraits, _It>::_Match_pat(_Node_base* _Nx) { // c case _N_none: default: - _Xregex_error(regex_constants::error_parse); +#if _ITERATOR_DEBUG_LEVEL != 0 + _STL_VERIFY(false, "internal data of regex node corrupted"); +#else // ^^^ _ITERATOR_DEBUG_LEVEL != 0 / _ITERATOR_DEBUG_LEVEL == 0 vvv + return false; +#endif // ^^^ _ITERATOR_DEBUG_LEVEL == 0 ^^^ } if (_Failed) { @@ -3950,9 +3984,9 @@ int _Parser<_FwdIt, _Elem, _RxTraits>::_Do_digits( } template -bool _Parser<_FwdIt, _Elem, _RxTraits>::_DecimalDigits( - regex_constants::error_type _Error_type) { // check for decimal value - return _Do_digits(10, INT_MAX, _Error_type) != INT_MAX; +bool _Parser<_FwdIt, _Elem, _RxTraits>::_DecimalDigits2( + const regex_constants::error_type _Error_type, const int _Count /* = INT_MAX */) { // check for decimal value + return _Do_digits(10, _Count, _Error_type) != _Count; } template @@ -3991,7 +4025,7 @@ void _Parser<_FwdIt, _Elem, _RxTraits>::_Do_ex_class( _Error(regex_constants::error_ctype); } - _Nfa._Add_named_class(_Cls); + _Nfa._Add_named_class(_Cls, false); } else if (_End_arg == _Meta_equal) { // process = if (_Beg == _Pat) { _Error(regex_constants::error_collate); @@ -4041,7 +4075,7 @@ _Prs_ret _Parser<_FwdIt, _Elem, _RxTraits>::_ClassEscape2() { // check for class return _Prs_chr; } else if ((_L_flags & _L_esc_wsd) && _CharacterClassEscape(false)) { return _Prs_set; - } else if (_DecimalDigits(regex_constants::error_escape)) { // check for invalid value + } else if (_DecimalDigits2(regex_constants::error_escape)) { // check for invalid value if (_Val != 0) { _Error(regex_constants::error_escape); } @@ -4113,16 +4147,22 @@ void _Parser<_FwdIt, _Elem, _RxTraits>::_ClassRanges() { // check for valid clas _Error(regex_constants::error_range); // set precedes or follows dash } - if (_Flags & regex_constants::collate) { // translate ends of range - _Val = _Traits.translate(static_cast<_Elem>(_Val)); + _Elem _Chr2 = static_cast<_Elem>(_Val); + + // translate ends of range + if (_Flags & regex_constants::icase) { + _Chr1 = _Traits.translate_nocase(_Chr1); + _Chr2 = _Traits.translate_nocase(_Chr2); + } else if (_Flags & regex_constants::collate) { _Chr1 = _Traits.translate(_Chr1); + _Chr2 = _Traits.translate(_Chr2); } - if (static_cast(_Val) < static_cast(_Chr1)) { + if (static_cast(_Chr2) < static_cast(_Chr1)) { _Error(regex_constants::error_range); } - _Nfa._Add_range(_Chr1, static_cast<_Elem>(_Val)); + _Nfa._Add_range2(_Chr1, _Chr2); } else if (_Ret == _Prs_chr) { _Nfa._Add_char_to_class(static_cast<_Elem>(_Val)); } @@ -4333,15 +4373,17 @@ bool _Parser<_FwdIt, _Elem, _RxTraits>::_CharacterEscape() { // check for valid template void _Parser<_FwdIt, _Elem, _RxTraits>::_AtomEscape() { // check for valid atom escape - if ((_L_flags & _L_bckr) && _DecimalDigits(regex_constants::error_backref)) { // check for valid back reference + constexpr int _Bre_max_backref_digits = 1; + if ((_L_flags & _L_bckr) + && _DecimalDigits2(regex_constants::error_backref, + (_L_flags & _L_lim_bckr) ? _Bre_max_backref_digits : INT_MAX)) { // check for valid back reference if (_Val == 0) { // handle \0 if (!(_L_flags & _L_bzr_chr)) { _Error(regex_constants::error_escape); } else { _Nfa._Add_char(static_cast<_Elem>(_Val)); } - } else if (((_L_flags & _L_lim_bckr) && _BRE_MAX_GRP < static_cast(_Val)) - || _Grp_idx < static_cast(_Val) || _Finished_grps.size() <= static_cast(_Val) + } else if (_Grp_idx < static_cast(_Val) || _Finished_grps.size() <= static_cast(_Val) || !_Finished_grps[static_cast(_Val)]) { _Error(regex_constants::error_backref); } else { @@ -4365,7 +4407,7 @@ void _Parser<_FwdIt, _Elem, _RxTraits>::_Quantifier() { // check for quantifier _Max = 1; } else if (_Mchar == _Meta_lbr) { // check for valid bracketed value _Next(); - if (!_DecimalDigits(regex_constants::error_badbrace)) { + if (!_DecimalDigits2(regex_constants::error_badbrace)) { _Error(regex_constants::error_badbrace); } @@ -4375,7 +4417,7 @@ void _Parser<_FwdIt, _Elem, _RxTraits>::_Quantifier() { // check for quantifier } else { // check for decimal constant following comma _Next(); if (_Mchar != _Meta_rbr) { - if (!_DecimalDigits(regex_constants::error_badbrace)) { + if (!_DecimalDigits2(regex_constants::error_badbrace)) { _Error(regex_constants::error_badbrace); } diff --git a/stl/inc/set b/stl/inc/set index 5e049118ad4..d78a0b88cfb 100644 --- a/stl/inc/set +++ b/stl/inc/set @@ -415,8 +415,8 @@ template <_RANGES input_range _Rng, class _Pr = less<_RANGES range_value_t<_Rng> multiset(from_range_t, _Rng&&, _Pr = _Pr(), _Alloc = _Alloc()) -> multiset<_RANGES range_value_t<_Rng>, _Pr, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -multiset( - from_range_t, _Rng&&, _Alloc) -> multiset<_RANGES range_value_t<_Rng>, less<_RANGES range_value_t<_Rng>>, _Alloc>; +multiset(from_range_t, _Rng&&, _Alloc) + -> multiset<_RANGES range_value_t<_Rng>, less<_RANGES range_value_t<_Rng>>, _Alloc>; #endif // _HAS_CXX23 #endif // _HAS_CXX17 diff --git a/stl/inc/thread b/stl/inc/thread index 09bda8e0e17..661eb6d2baf 100644 --- a/stl/inc/thread +++ b/stl/inc/thread @@ -169,7 +169,7 @@ _NODISCARD auto _To_absolute_time(const chrono::duration<_Rep, _Period>& _Rel_ti const auto _Now = chrono::steady_clock::now(); decltype(_Now + _Rel_time) _Abs_time = _Now; // return common type if (_Rel_time > _Zero) { - constexpr auto _Forever = (chrono::steady_clock::time_point::max)(); + constexpr auto _Forever = (decltype(_Abs_time)::max)(); if (_Abs_time < _Forever - _Rel_time) { _Abs_time += _Rel_time; } else { diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 8edd5d4c62b..7ba2935d369 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -1659,8 +1659,8 @@ struct _Invoker_pmd_pointer { static constexpr _Invoker_strategy _Strategy = _Invoker_strategy::_Pmd_pointer; template - static constexpr auto _Call(_Decayed _Pmd, _Ty1&& _Arg1) - noexcept(noexcept((*static_cast<_Ty1&&>(_Arg1)).*_Pmd)) -> decltype((*static_cast<_Ty1&&>(_Arg1)).*_Pmd) { + static constexpr auto _Call(_Decayed _Pmd, _Ty1&& _Arg1) noexcept(noexcept((*static_cast<_Ty1&&>(_Arg1)).*_Pmd)) + -> decltype((*static_cast<_Ty1&&>(_Arg1)).*_Pmd) { return (*static_cast<_Ty1&&>(_Arg1)).*_Pmd; } }; @@ -1691,8 +1691,8 @@ template struct _Invoker1<_Callable, _Ty1, _Removed_cvref, false, false> : _Invoker_functor {}; _EXPORT_STD template -constexpr auto invoke(_Callable&& _Obj) - noexcept(noexcept(static_cast<_Callable&&>(_Obj)())) -> decltype(static_cast<_Callable&&>(_Obj)()) { +constexpr auto invoke(_Callable&& _Obj) noexcept(noexcept(static_cast<_Callable&&>(_Obj)())) + -> decltype(static_cast<_Callable&&>(_Obj)()) { return static_cast<_Callable&&>(_Obj)(); } @@ -1912,12 +1912,12 @@ _EXPORT_STD template constexpr bool is_pointer_interconvertible_base_of_v = __is_pointer_interconvertible_base_of(_Base, _Derived); _EXPORT_STD template -_NODISCARD constexpr bool is_pointer_interconvertible_with_class(_MemberTy _ClassTy::*_Pm) noexcept { +_NODISCARD constexpr bool is_pointer_interconvertible_with_class(_MemberTy _ClassTy::* _Pm) noexcept { return __is_pointer_interconvertible_with_class(_ClassTy, _Pm); } _EXPORT_STD template -_NODISCARD constexpr bool is_corresponding_member(_MemberTy1 _ClassTy1::*_Pm1, _MemberTy2 _ClassTy2::*_Pm2) noexcept { +_NODISCARD constexpr bool is_corresponding_member(_MemberTy1 _ClassTy1::* _Pm1, _MemberTy2 _ClassTy2::* _Pm2) noexcept { return __is_corresponding_member(_ClassTy1, _ClassTy2, _Pm1, _Pm2); } #endif // ^^^ no workaround ^^^ @@ -2299,7 +2299,7 @@ _NODISCARD inline size_t _Fnv1a_append_bytes(size_t _Val, const unsigned char* c template _NODISCARD size_t _Fnv1a_append_range(const size_t _Val, const _Ty* const _First, const _Ty* const _Last) noexcept { // accumulate range [_First, _Last) into partial FNV-1a hash _Val - static_assert(is_trivial_v<_Ty>, "Only trivial types can be directly hashed."); + static_assert(is_trivially_copyable_v<_Ty>, "Only trivially copyable types can be directly hashed."); const auto _Firstb = reinterpret_cast(_First); const auto _Lastb = reinterpret_cast(_Last); return _Fnv1a_append_bytes(_Val, _Firstb, static_cast(_Lastb - _Firstb)); @@ -2308,7 +2308,7 @@ _NODISCARD size_t _Fnv1a_append_range(const size_t _Val, const _Ty* const _First template _NODISCARD size_t _Fnv1a_append_value( const size_t _Val, const _Kty& _Keyval) noexcept { // accumulate _Keyval into partial FNV-1a hash _Val - static_assert(is_trivial_v<_Kty>, "Only trivial types can be directly hashed."); + static_assert(is_trivially_copyable_v<_Kty>, "Only trivially copyable types can be directly hashed."); return _Fnv1a_append_bytes(_Val, &reinterpret_cast(_Keyval), sizeof(_Kty)); } @@ -2320,7 +2320,7 @@ _NODISCARD size_t _Hash_representation(const _Kty& _Keyval) noexcept { // bitwis template _NODISCARD size_t _Hash_array_representation( const _Kty* const _First, const size_t _Count) noexcept { // bitwise hashes the representation of an array - static_assert(is_trivial_v<_Kty>, "Only trivial types can be directly hashed."); + static_assert(is_trivially_copyable_v<_Kty>, "Only trivially copyable types can be directly hashed."); return _Fnv1a_append_bytes( _FNV_offset_basis, reinterpret_cast(_First), _Count * sizeof(_Kty)); } diff --git a/stl/inc/unordered_map b/stl/inc/unordered_map index b8aff218ae4..b7f4891cf82 100644 --- a/stl/inc/unordered_map +++ b/stl/inc/unordered_map @@ -461,8 +461,8 @@ template >, class _Keyeq = enable_if_t< conjunction_v<_Is_iterator<_Iter>, _Is_hasher<_Hasher>, negation<_Is_allocator<_Keyeq>>, _Is_allocator<_Alloc>>, int> = 0> -unordered_map(_Iter, _Iter, _Guide_size_type_t<_Alloc> = 0, _Hasher = _Hasher(), _Keyeq = _Keyeq(), - _Alloc = _Alloc()) -> unordered_map<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, _Hasher, _Keyeq, _Alloc>; +unordered_map(_Iter, _Iter, _Guide_size_type_t<_Alloc> = 0, _Hasher = _Hasher(), _Keyeq = _Keyeq(), _Alloc = _Alloc()) + -> unordered_map<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, _Hasher, _Keyeq, _Alloc>; template , class _Keyeq = equal_to<_Kty>, class _Alloc = allocator>, @@ -472,30 +472,29 @@ unordered_map(initializer_list>, _Guide_size_type_t<_Alloc> = 0, template , _Is_allocator<_Alloc>>, int> = 0> unordered_map(_Iter, _Iter, _Alloc) -> unordered_map<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, - hash<_Guide_key_t<_Iter>>, equal_to<_Guide_key_t<_Iter>>, _Alloc>; + hash<_Guide_key_t<_Iter>>, equal_to<_Guide_key_t<_Iter>>, _Alloc>; template , _Is_allocator<_Alloc>>, int> = 0> -unordered_map(_Iter, _Iter, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_map<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, hash<_Guide_key_t<_Iter>>, - equal_to<_Guide_key_t<_Iter>>, _Alloc>; +unordered_map(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Alloc) -> unordered_map<_Guide_key_t<_Iter>, + _Guide_val_t<_Iter>, hash<_Guide_key_t<_Iter>>, equal_to<_Guide_key_t<_Iter>>, _Alloc>; template , _Is_hasher<_Hasher>, _Is_allocator<_Alloc>>, int> = 0> -unordered_map(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_map<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, _Hasher, equal_to<_Guide_key_t<_Iter>>, _Alloc>; +unordered_map(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_map<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, _Hasher, equal_to<_Guide_key_t<_Iter>>, _Alloc>; template ::value, int> = 0> -unordered_map( - initializer_list>, _Alloc) -> unordered_map<_Kty, _Ty, hash<_Kty>, equal_to<_Kty>, _Alloc>; +unordered_map(initializer_list>, _Alloc) + -> unordered_map<_Kty, _Ty, hash<_Kty>, equal_to<_Kty>, _Alloc>; template ::value, int> = 0> -unordered_map(initializer_list>, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_map<_Kty, _Ty, hash<_Kty>, equal_to<_Kty>, _Alloc>; +unordered_map(initializer_list>, _Guide_size_type_t<_Alloc>, _Alloc) + -> unordered_map<_Kty, _Ty, hash<_Kty>, equal_to<_Kty>, _Alloc>; template , _Is_allocator<_Alloc>>, int> = 0> -unordered_map(initializer_list>, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_map<_Kty, _Ty, _Hasher, equal_to<_Kty>, _Alloc>; +unordered_map(initializer_list>, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_map<_Kty, _Ty, _Hasher, equal_to<_Kty>, _Alloc>; #if _HAS_CXX23 template <_RANGES input_range _Rng, _Hasher_for_container _Hasher = hash<_Range_key_type<_Rng>>, @@ -506,13 +505,12 @@ unordered_map(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc> = 0, _Hasher = _H _Alloc = _Alloc()) -> unordered_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Hasher, _Keyeq, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -unordered_map(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, hash<_Range_key_type<_Rng>>, - equal_to<_Range_key_type<_Rng>>, _Alloc>; +unordered_map(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Alloc) -> unordered_map<_Range_key_type<_Rng>, + _Range_mapped_type<_Rng>, hash<_Range_key_type<_Rng>>, equal_to<_Range_key_type<_Rng>>, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> unordered_map(from_range_t, _Rng&&, _Alloc) -> unordered_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, - hash<_Range_key_type<_Rng>>, equal_to<_Range_key_type<_Rng>>, _Alloc>; + hash<_Range_key_type<_Rng>>, equal_to<_Range_key_type<_Rng>>, _Alloc>; template <_RANGES input_range _Rng, _Hasher_for_container _Hasher, _Allocator_for_container _Alloc> unordered_map(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) @@ -844,12 +842,11 @@ unordered_multimap(initializer_list>, _Guide_size_type_t<_Alloc> template , _Is_allocator<_Alloc>>, int> = 0> unordered_multimap(_Iter, _Iter, _Alloc) -> unordered_multimap<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, - hash<_Guide_key_t<_Iter>>, equal_to<_Guide_key_t<_Iter>>, _Alloc>; + hash<_Guide_key_t<_Iter>>, equal_to<_Guide_key_t<_Iter>>, _Alloc>; template , _Is_allocator<_Alloc>>, int> = 0> -unordered_multimap(_Iter, _Iter, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_multimap<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, hash<_Guide_key_t<_Iter>>, - equal_to<_Guide_key_t<_Iter>>, _Alloc>; +unordered_multimap(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Alloc) -> unordered_multimap<_Guide_key_t<_Iter>, + _Guide_val_t<_Iter>, hash<_Guide_key_t<_Iter>>, equal_to<_Guide_key_t<_Iter>>, _Alloc>; template , _Is_hasher<_Hasher>, _Is_allocator<_Alloc>>, int> = 0> @@ -857,17 +854,17 @@ unordered_multimap(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) -> unordered_multimap<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, _Hasher, equal_to<_Guide_key_t<_Iter>>, _Alloc>; template ::value, int> = 0> -unordered_multimap( - initializer_list>, _Alloc) -> unordered_multimap<_Kty, _Ty, hash<_Kty>, equal_to<_Kty>, _Alloc>; +unordered_multimap(initializer_list>, _Alloc) + -> unordered_multimap<_Kty, _Ty, hash<_Kty>, equal_to<_Kty>, _Alloc>; template ::value, int> = 0> -unordered_multimap(initializer_list>, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_multimap<_Kty, _Ty, hash<_Kty>, equal_to<_Kty>, _Alloc>; +unordered_multimap(initializer_list>, _Guide_size_type_t<_Alloc>, _Alloc) + -> unordered_multimap<_Kty, _Ty, hash<_Kty>, equal_to<_Kty>, _Alloc>; template , _Is_allocator<_Alloc>>, int> = 0> -unordered_multimap(initializer_list>, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_multimap<_Kty, _Ty, _Hasher, equal_to<_Kty>, _Alloc>; +unordered_multimap(initializer_list>, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_multimap<_Kty, _Ty, _Hasher, equal_to<_Kty>, _Alloc>; #if _HAS_CXX23 template <_RANGES input_range _Rng, _Hasher_for_container _Hasher = hash<_Range_key_type<_Rng>>, @@ -878,19 +875,18 @@ unordered_multimap(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc> = 0, _Hasher _Alloc = _Alloc()) -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Hasher, _Keyeq, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -unordered_multimap(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, hash<_Range_key_type<_Rng>>, - equal_to<_Range_key_type<_Rng>>, _Alloc>; +unordered_multimap(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Alloc) + -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, hash<_Range_key_type<_Rng>>, + equal_to<_Range_key_type<_Rng>>, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -unordered_multimap( - from_range_t, _Rng&&, _Alloc) -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, - hash<_Range_key_type<_Rng>>, equal_to<_Range_key_type<_Rng>>, _Alloc>; +unordered_multimap(from_range_t, _Rng&&, _Alloc) -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, + hash<_Range_key_type<_Rng>>, equal_to<_Range_key_type<_Rng>>, _Alloc>; template <_RANGES input_range _Rng, _Hasher_for_container _Hasher, _Allocator_for_container _Alloc> -unordered_multimap(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Hasher, - equal_to<_Range_key_type<_Rng>>, _Alloc>; +unordered_multimap(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Hasher, equal_to<_Range_key_type<_Rng>>, + _Alloc>; #endif // _HAS_CXX23 #endif // _HAS_CXX17 diff --git a/stl/inc/unordered_set b/stl/inc/unordered_set index 7e49770386f..0f41d148e97 100644 --- a/stl/inc/unordered_set +++ b/stl/inc/unordered_set @@ -326,8 +326,8 @@ template >, class _Keyeq enable_if_t< conjunction_v<_Is_iterator<_Iter>, _Is_hasher<_Hasher>, negation<_Is_allocator<_Keyeq>>, _Is_allocator<_Alloc>>, int> = 0> -unordered_set(_Iter, _Iter, _Guide_size_type_t<_Alloc> = 0, _Hasher = _Hasher(), _Keyeq = _Keyeq(), - _Alloc = _Alloc()) -> unordered_set<_Iter_value_t<_Iter>, _Hasher, _Keyeq, _Alloc>; +unordered_set(_Iter, _Iter, _Guide_size_type_t<_Alloc> = 0, _Hasher = _Hasher(), _Keyeq = _Keyeq(), _Alloc = _Alloc()) + -> unordered_set<_Iter_value_t<_Iter>, _Hasher, _Keyeq, _Alloc>; template , class _Keyeq = equal_to<_Kty>, class _Alloc = allocator<_Kty>, enable_if_t, negation<_Is_allocator<_Keyeq>>, _Is_allocator<_Alloc>>, int> = 0> @@ -335,22 +335,22 @@ unordered_set(initializer_list<_Kty>, _Guide_size_type_t<_Alloc> = 0, _Hasher = _Alloc = _Alloc()) -> unordered_set<_Kty, _Hasher, _Keyeq, _Alloc>; template , _Is_allocator<_Alloc>>, int> = 0> -unordered_set(_Iter, _Iter, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_set<_Iter_value_t<_Iter>, hash<_Iter_value_t<_Iter>>, equal_to<_Iter_value_t<_Iter>>, _Alloc>; +unordered_set(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Alloc) + -> unordered_set<_Iter_value_t<_Iter>, hash<_Iter_value_t<_Iter>>, equal_to<_Iter_value_t<_Iter>>, _Alloc>; template , _Is_hasher<_Hasher>, _Is_allocator<_Alloc>>, int> = 0> -unordered_set(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_set<_Iter_value_t<_Iter>, _Hasher, equal_to<_Iter_value_t<_Iter>>, _Alloc>; +unordered_set(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_set<_Iter_value_t<_Iter>, _Hasher, equal_to<_Iter_value_t<_Iter>>, _Alloc>; template ::value, int> = 0> -unordered_set(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_set<_Kty, hash<_Kty>, equal_to<_Kty>, _Alloc>; +unordered_set(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, _Alloc) + -> unordered_set<_Kty, hash<_Kty>, equal_to<_Kty>, _Alloc>; template , _Is_allocator<_Alloc>>, int> = 0> -unordered_set(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_set<_Kty, _Hasher, equal_to<_Kty>, _Alloc>; +unordered_set(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_set<_Kty, _Hasher, equal_to<_Kty>, _Alloc>; #if _HAS_CXX23 template <_RANGES input_range _Rng, _Hasher_for_container _Hasher = hash<_RANGES range_value_t<_Rng>>, @@ -361,18 +361,16 @@ unordered_set(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc> = 0, _Hasher = _H _Alloc = _Alloc()) -> unordered_set<_RANGES range_value_t<_Rng>, _Hasher, _Keyeq, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -unordered_set(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_set<_RANGES range_value_t<_Rng>, hash<_RANGES range_value_t<_Rng>>, - equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; +unordered_set(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Alloc) -> unordered_set<_RANGES range_value_t<_Rng>, + hash<_RANGES range_value_t<_Rng>>, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -unordered_set( - from_range_t, _Rng&&, _Alloc) -> unordered_set<_RANGES range_value_t<_Rng>, hash<_RANGES range_value_t<_Rng>>, - equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; +unordered_set(from_range_t, _Rng&&, _Alloc) -> unordered_set<_RANGES range_value_t<_Rng>, + hash<_RANGES range_value_t<_Rng>>, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; template <_RANGES input_range _Rng, _Hasher_for_container _Hasher, _Allocator_for_container _Alloc> -unordered_set(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_set<_RANGES range_value_t<_Rng>, _Hasher, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; +unordered_set(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_set<_RANGES range_value_t<_Rng>, _Hasher, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; #endif // _HAS_CXX23 #endif // _HAS_CXX17 @@ -685,17 +683,17 @@ unordered_multiset(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Alloc) template , _Is_hasher<_Hasher>, _Is_allocator<_Alloc>>, int> = 0> -unordered_multiset(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_multiset<_Iter_value_t<_Iter>, _Hasher, equal_to<_Iter_value_t<_Iter>>, _Alloc>; +unordered_multiset(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_multiset<_Iter_value_t<_Iter>, _Hasher, equal_to<_Iter_value_t<_Iter>>, _Alloc>; template ::value, int> = 0> -unordered_multiset(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_multiset<_Kty, hash<_Kty>, equal_to<_Kty>, _Alloc>; +unordered_multiset(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, _Alloc) + -> unordered_multiset<_Kty, hash<_Kty>, equal_to<_Kty>, _Alloc>; template , _Is_allocator<_Alloc>>, int> = 0> -unordered_multiset(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_multiset<_Kty, _Hasher, equal_to<_Kty>, _Alloc>; +unordered_multiset(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_multiset<_Kty, _Hasher, equal_to<_Kty>, _Alloc>; #if _HAS_CXX23 template <_RANGES input_range _Rng, _Hasher_for_container _Hasher = hash<_RANGES range_value_t<_Rng>>, @@ -706,18 +704,17 @@ unordered_multiset(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc> = 0, _Hasher _Alloc = _Alloc()) -> unordered_multiset<_RANGES range_value_t<_Rng>, _Hasher, _Keyeq, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -unordered_multiset(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_multiset<_RANGES range_value_t<_Rng>, hash<_RANGES range_value_t<_Rng>>, - equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; +unordered_multiset(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Alloc) + -> unordered_multiset<_RANGES range_value_t<_Rng>, hash<_RANGES range_value_t<_Rng>>, + equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -unordered_multiset( - from_range_t, _Rng&&, _Alloc) -> unordered_multiset<_RANGES range_value_t<_Rng>, hash<_RANGES range_value_t<_Rng>>, - equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; +unordered_multiset(from_range_t, _Rng&&, _Alloc) -> unordered_multiset<_RANGES range_value_t<_Rng>, + hash<_RANGES range_value_t<_Rng>>, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; template <_RANGES input_range _Rng, _Hasher_for_container _Hasher, _Allocator_for_container _Alloc> -unordered_multiset(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_multiset<_RANGES range_value_t<_Rng>, _Hasher, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; +unordered_multiset(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_multiset<_RANGES range_value_t<_Rng>, _Hasher, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; #endif // _HAS_CXX23 #endif // _HAS_CXX17 diff --git a/stl/inc/utility b/stl/inc/utility index 4fc04c67f4f..ae7f4094f14 100644 --- a/stl/inc/utility +++ b/stl/inc/utility @@ -319,7 +319,7 @@ struct pair { // store a pair of values is_constructible<_Ty2, decltype(_STD get<1>(_STD declval<_Other>()))>> #endif // ^^^ no workaround ^^^ constexpr explicit(!conjunction_v(_STD declval<_Other>())), _Ty1>, - is_convertible(_STD declval<_Other>())), _Ty2>>) pair(_Other&& _Right) + is_convertible(_STD declval<_Other>())), _Ty2>>) pair(_Other&& _Right) noexcept(is_nothrow_constructible_v<_Ty1, decltype(_STD get<0>(_STD declval<_Other>()))> && is_nothrow_constructible_v<_Ty2, decltype(_STD get<1>(_STD declval<_Other>()))>) // strengthened : first(_STD get<0>(_STD forward<_Other>(_Right))), second(_STD get<1>(_STD forward<_Other>(_Right))) { diff --git a/stl/inc/variant b/stl/inc/variant index ac38081fe06..8d472e9ca24 100644 --- a/stl/inc/variant +++ b/stl/inc/variant @@ -499,17 +499,14 @@ _NODISCARD constexpr decltype(auto) _Variant_raw_get(_Storage&& _Obj) noexcept { return _STD _Variant_raw_get<_Idx - 8>( static_cast<_Storage&&>(_Obj)._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail); } else if constexpr (_Idx < 32) { - return _STD _Variant_raw_get<_Idx - 16>( - static_cast<_Storage&&>(_Obj) + return _STD _Variant_raw_get<_Idx - 16>(static_cast<_Storage&&>(_Obj) ._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail); } else if constexpr (_Idx < 64) { - return _STD _Variant_raw_get<_Idx - 32>( - static_cast<_Storage&&>(_Obj) + return _STD _Variant_raw_get<_Idx - 32>(static_cast<_Storage&&>(_Obj) ._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail ._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail); } else { // _Idx >= 64 - return _STD _Variant_raw_get<_Idx - 64>( - static_cast<_Storage&&>(_Obj) + return _STD _Variant_raw_get<_Idx - 64>(static_cast<_Storage&&>(_Obj) ._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail ._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail ._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail diff --git a/stl/inc/xcall_once.h b/stl/inc/xcall_once.h index 8874e232f81..7d484899160 100644 --- a/stl/inc/xcall_once.h +++ b/stl/inc/xcall_once.h @@ -40,7 +40,8 @@ union _Immortalizer_impl { // constructs _Ty, never destroys _Ty _Storage; }; -#if defined(_M_CEE) || defined(_M_ARM64EC) || defined(_M_HYBRID) +#if defined(_M_CEE) || defined(_M_ARM64EC) || defined(_M_HYBRID) \ + || defined(__clang__) // TRANSITION, avoid /ALTERNATENAME for Clang, see GH-5224 #define _WINDOWS_API __stdcall #define _RENAME_WINDOWS_API(_Api) _Api##_clr #else // ^^^ use forwarders / use /ALTERNATENAME vvv diff --git a/stl/inc/xhash b/stl/inc/xhash index 33854c4af0a..0df519a86ff 100644 --- a/stl/inc/xhash +++ b/stl/inc/xhash @@ -96,13 +96,7 @@ _STD_BEGIN template struct _Uhash_choose_transparency { // transparency selector for non-transparent hashed containers - template - using _Deduce_key = const _Kty&; - -#if _HAS_CXX20 && defined(__EDG__) // TRANSITION, DevCom-10678753 - template - static constexpr bool _Supports_transparency = false; -#endif // ^^^ workaround ^^^ + static constexpr bool _Has_transparent_overloads = false; }; #if _HAS_CXX20 @@ -110,8 +104,7 @@ template requires _Is_transparent_v<_Hasher> && _Is_transparent_v<_Keyeq> struct _Uhash_choose_transparency<_Kty, _Hasher, _Keyeq> { // transparency selector for transparent hashed containers - template - using _Deduce_key = const _Keyty&; + static constexpr bool _Has_transparent_overloads = true; template static constexpr bool _Supports_transparency = @@ -1225,25 +1218,53 @@ private: } public: - template - _NODISCARD iterator find(typename _Traits::template _Deduce_key<_Keyty> _Keyval) { + _NODISCARD iterator find(const key_type& _Keyval) { return _List._Make_iter(_Find(_Keyval, _Traitsobj(_Keyval))); } - template - _NODISCARD const_iterator find(typename _Traits::template _Deduce_key<_Keyty> _Keyval) const { +#if _HAS_CXX20 + template + requires _Traits::_Has_transparent_overloads + _NODISCARD iterator find(const _KeyTy& _Keyval) { + return _List._Make_iter(_Find(_Keyval, _Traitsobj(_Keyval))); + } +#endif // _HAS_CXX20 + + _NODISCARD const_iterator find(const key_type& _Keyval) const { return _List._Make_const_iter(_Find(_Keyval, _Traitsobj(_Keyval))); } #if _HAS_CXX20 - template - _NODISCARD bool contains(_Traits::template _Deduce_key<_Keyty> _Keyval) const { + template + requires _Traits::_Has_transparent_overloads + _NODISCARD const_iterator find(const _KeyTy& _Keyval) const { + return _List._Make_const_iter(_Find(_Keyval, _Traitsobj(_Keyval))); + } + + _NODISCARD bool contains(const key_type& _Keyval) const { + return static_cast(_Find_last(_Keyval, _Traitsobj(_Keyval))._Duplicate); + } + + template + requires _Traits::_Has_transparent_overloads + _NODISCARD bool contains(const _KeyTy& _Keyval) const { return static_cast(_Find_last(_Keyval, _Traitsobj(_Keyval))._Duplicate); } #endif // _HAS_CXX20 - template - _NODISCARD size_type count(typename _Traits::template _Deduce_key<_Keyty> _Keyval) const { + _NODISCARD size_type count(const key_type& _Keyval) const { + const size_t _Hashval = _Traitsobj(_Keyval); + if constexpr (_Multi) { + return _Equal_range(_Keyval, _Hashval)._Distance; + } else { + return static_cast(_Find_last(_Keyval, _Hashval)._Duplicate); + } + } + +#if _HAS_CXX20 + template + requires _Traits::_Has_transparent_overloads + _NODISCARD size_type count(const _KeyTy& _Keyval) const { const size_t _Hashval = _Traitsobj(_Keyval); if constexpr (_Multi) { return _Equal_range(_Keyval, _Hashval)._Distance; @@ -1251,6 +1272,7 @@ public: return static_cast(_Find_last(_Keyval, _Hashval)._Duplicate); } } +#endif // _HAS_CXX20 private: struct _Equal_range_result { @@ -1307,19 +1329,34 @@ private: } public: - template - _NODISCARD pair equal_range(typename _Traits::template _Deduce_key<_Keyty> _Keyval) { + _NODISCARD pair equal_range(const key_type& _Keyval) { + const auto _Result = _Equal_range(_Keyval, _Traitsobj(_Keyval)); + return {_List._Make_iter(_Result._First._Ptr), _List._Make_iter(_Result._Last._Ptr)}; + } + +#if _HAS_CXX20 + template + requires _Traits::_Has_transparent_overloads + _NODISCARD pair equal_range(const _KeyTy& _Keyval) { const auto _Result = _Equal_range(_Keyval, _Traitsobj(_Keyval)); return {_List._Make_iter(_Result._First._Ptr), _List._Make_iter(_Result._Last._Ptr)}; } +#endif // _HAS_CXX20 - template - _NODISCARD pair equal_range( - typename _Traits::template _Deduce_key<_Keyty> _Keyval) const { + _NODISCARD pair equal_range(const key_type& _Keyval) const { const auto _Result = _Equal_range(_Keyval, _Traitsobj(_Keyval)); return {_List._Make_const_iter(_Result._First._Ptr), _List._Make_const_iter(_Result._Last._Ptr)}; } +#if _HAS_CXX20 + template + requires _Traits::_Has_transparent_overloads + _NODISCARD pair equal_range(const _KeyTy& _Keyval) const { + const auto _Result = _Equal_range(_Keyval, _Traitsobj(_Keyval)); + return {_List._Make_const_iter(_Result._First._Ptr), _List._Make_const_iter(_Result._Last._Ptr)}; + } +#endif // _HAS_CXX20 + void swap(_Hash& _Right) noexcept(noexcept(_Traitsobj.swap(_Right._Traitsobj))) /* strengthened */ { if (this != _STD addressof(_Right)) { _Traitsobj.swap(_Right._Traitsobj); diff --git a/stl/inc/xlocale b/stl/inc/xlocale index 40f3719d527..77c8d1b4c9b 100644 --- a/stl/inc/xlocale +++ b/stl/inc/xlocale @@ -28,6 +28,7 @@ class _Locbase {}; // TRANSITION, ABI, affects sizeof(locale) _EXPORT_STD template class collate; +// clang-format off: clang-format 19 doesn't understand _CRTIMP2_PURE_IMPORT and will poorly format the following code extern "C++" struct _CRTIMP2_PURE_IMPORT _Crt_new_delete { // base class for marking allocations as CRT blocks #ifdef _DEBUG void* __CLRCALL_OR_CDECL operator new(size_t _Size) { // replace operator new @@ -58,6 +59,7 @@ extern "C++" struct _CRTIMP2_PURE_IMPORT _Crt_new_delete { // base class for mar void __CLRCALL_OR_CDECL operator delete(void*, void*) noexcept {} // imitate True Placement Delete #endif // _DEBUG }; +// clang-format on _EXPORT_STD extern "C++" class locale : public _Locbase, public _Crt_new_delete { public: @@ -400,7 +402,8 @@ public: static _MRTIMP2_PURE locale __CLRCALL_PURE_OR_CDECL global(const locale&); // current locale - static _MRTIMP2_PURE locale __CLRCALL_PURE_OR_CDECL empty(); // empty (transparent) locale + // TRANSITION, ABI: non-Standard empty() is preserved for binary compatibility + _DEPRECATE_LOCALE_EMPTY static _MRTIMP2_PURE locale __CLRCALL_PURE_OR_CDECL empty(); // empty (transparent) locale private: struct _Secret_locale_construct_tag { diff --git a/stl/inc/xlocnum b/stl/inc/xlocnum index 36682328eb6..5cf765bec5d 100644 --- a/stl/inc/xlocnum +++ b/stl/inc/xlocnum @@ -878,7 +878,7 @@ private: const size_t _Offset_digit_end = _Parse_hex ? _Offset_hex_digit_end : _Offset_dec_digit_end; if (_Grouping.empty()) { for (size_t _Idx; _First != _Last && (_Idx = _STD _Find_elem(_Atoms, *_First)) < _Offset_digit_end; - _Seendigit = true, (void) ++_First) { + _Seendigit = true, (void) ++_First) { if (_Significant >= _Max_sig_dig) { ++_Power_of_rep_base; // just scale by 10 or 16 if (_Idx > 0) { @@ -977,7 +977,7 @@ private: } for (size_t _Idx; _First != _Last && (_Idx = _STD _Find_elem(_Atoms, *_First)) < _Offset_digit_end; - _Seendigit = true, (void) ++_First) { + _Seendigit = true, (void) ++_First) { if (_Significant < _Max_sig_dig) { // save a significant fraction digit *_Ptr++ = _Src[_Idx]; ++_Significant; @@ -1018,7 +1018,7 @@ private: } for (size_t _Idx; _First != _Last && (_Idx = _STD _Find_elem(_Atoms, *_First)) < _Offset_dec_digit_end; - _Seendigit = true, (void) ++_First) { + _Seendigit = true, (void) ++_First) { if (_Exponent_part < PTRDIFF_MAX / 10 || (_Exponent_part == PTRDIFF_MAX / 10 && static_cast(_Idx) <= PTRDIFF_MAX % 10)) { // save a significant exponent digit @@ -1091,7 +1091,7 @@ private: char* const _Rev_begin = _Ptr; for (ptrdiff_t _Exponent_part_abs = _STD abs(_Exponent_part); _Exponent_part_abs != 0; - _Exponent_part_abs /= 10) { + _Exponent_part_abs /= 10) { *_Ptr++ = static_cast('0' + _Exponent_part_abs % 10); } _STD reverse(_Rev_begin, _Ptr); diff --git a/stl/inc/xloctime b/stl/inc/xloctime index b48e1b1d25f..9534cdefddf 100644 --- a/stl/inc/xloctime +++ b/stl/inc/xloctime @@ -55,8 +55,8 @@ ios_base::iostate _Getint_v2(_InIt& _First, _InIt& _Last, int _Lo, int _Hi, int& } for (char* const _Pe = &_Ac[_Max_int_dig - 1]; - _First != _Last && '0' <= (_Ch = _Ctype_fac.narrow(*_First)) && _Ch <= '9' && _Digits_read < _Hi_digits; - ++_Digits_read, (void) ++_First) { // copy digits + _First != _Last && '0' <= (_Ch = _Ctype_fac.narrow(*_First)) && _Ch <= '9' && _Digits_read < _Hi_digits; + ++_Digits_read, (void) ++_First) { // copy digits *_Ptr = _Ch; if (_Ptr < _Pe) { ++_Ptr; // drop trailing digits if already too large diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 462a7465fc5..7567d415a15 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -1663,7 +1663,9 @@ _NoThrowFwdIt _Uninitialized_move_unchecked(_InIt _First, const _InIt _Last, _No #if 0 // TRANSITION, _HAS_CXX26 if (!_STD is_constant_evaluated()) #endif // _HAS_CXX26 - { return _STD _Copy_memmove(_First, _Last, _Dest); } + { + return _STD _Copy_memmove(_First, _Last, _Dest); + } } _Uninitialized_backout<_NoThrowFwdIt> _Backout{_Dest}; for (; _First != _Last; ++_First) { @@ -1934,7 +1936,9 @@ _NoThrowFwdIt _Uninitialized_copy_unchecked(_InIt _First, const _InIt _Last, _No #if 0 // TRANSITION, _HAS_CXX26 if (!_STD is_constant_evaluated()) #endif // _HAS_CXX26 - { return _STD _Copy_memmove(_First, _Last, _Dest); } + { + return _STD _Copy_memmove(_First, _Last, _Dest); + } } _Uninitialized_backout<_NoThrowFwdIt> _Backout{_Dest}; diff --git a/stl/inc/xstring b/stl/inc/xstring index e39cb1871a3..ea4393dae3d 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -538,9 +538,10 @@ private: "N4950 [string.require]/3 requires that the supplied " "char_traits character type match the string's character type."); - static_assert(!is_array_v<_Elem> && is_trivial_v<_Elem> && is_standard_layout_v<_Elem>, - "The character type of basic_string must be a non-array trivial standard-layout type. See N4950 " - "[strings.general]/1."); + static_assert(!is_array_v<_Elem> && is_trivially_copyable_v<_Elem> && is_trivially_default_constructible_v<_Elem> + && is_standard_layout_v<_Elem>, + "The character type of basic_string must be a non-array trivially copyable standard-layout type T where " + "is_trivially_default_constructible_v is true. See N5001 [strings.general]/1."); public: using traits_type = _Traits; @@ -573,12 +574,13 @@ private: // _String_val::_Bx::_Ptr (type is pointer) // _String_val::_Mysize (type is size_type) // _String_val::_Myres (type is size_type) - // N4950 [strings.general]/1 says _Elem must be trivial standard-layout, so memcpy is safe. + // N5001 [strings.general]/1 says _Elem must be trivially copyable standard-layout, so memcpy is safe. // We need to ask if pointer is safe to memcpy. // size_type must be an unsigned integral type so memcpy is safe. // We also need to disable memcpy if the user has supplied _Traits, since // they can observe traits::assign and similar. - static constexpr bool _Can_memcpy_val = _Is_specialization_v<_Traits, char_traits> && is_trivial_v; + static constexpr bool _Can_memcpy_val = + _Is_specialization_v<_Traits, char_traits> && is_trivially_copyable_v; // This offset skips over the _Container_base members, if any static constexpr size_t _Memcpy_val_offset = _Size_after_ebco_v<_Container_base>; static constexpr size_t _Memcpy_val_size = sizeof(_Scary_val) - _Memcpy_val_offset; @@ -3081,13 +3083,13 @@ private: #if _HAS_CXX17 template >, enable_if_t, _Is_allocator<_Alloc>>, int> = 0> -basic_string( - _Iter, _Iter, _Alloc = _Alloc()) -> basic_string<_Iter_value_t<_Iter>, char_traits<_Iter_value_t<_Iter>>, _Alloc>; +basic_string(_Iter, _Iter, _Alloc = _Alloc()) + -> basic_string<_Iter_value_t<_Iter>, char_traits<_Iter_value_t<_Iter>>, _Alloc>; template , enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> -explicit basic_string( - basic_string_view<_Elem, _Traits>, const _Alloc& = _Alloc()) -> basic_string<_Elem, _Traits, _Alloc>; +explicit basic_string(basic_string_view<_Elem, _Traits>, const _Alloc& = _Alloc()) + -> basic_string<_Elem, _Traits, _Alloc>; template , enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> @@ -3096,8 +3098,8 @@ basic_string(basic_string_view<_Elem, _Traits>, _Guide_size_type_t<_Alloc>, _Gui #if _HAS_CXX23 template <_RANGES input_range _Rng, _Allocator_for_container _Alloc = allocator<_RANGES range_value_t<_Rng>>> -basic_string(from_range_t, _Rng&&, - _Alloc = _Alloc()) -> basic_string<_RANGES range_value_t<_Rng>, char_traits<_RANGES range_value_t<_Rng>>, _Alloc>; +basic_string(from_range_t, _Rng&&, _Alloc = _Alloc()) + -> basic_string<_RANGES range_value_t<_Rng>, char_traits<_RANGES range_value_t<_Rng>>, _Alloc>; #endif // _HAS_CXX23 #endif // _HAS_CXX17 diff --git a/stl/inc/xutility b/stl/inc/xutility index f1f33652ce7..d31e7079341 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -2033,14 +2033,14 @@ _NODISCARD constexpr _Ty* end(_Ty (&_Array)[_Size]) noexcept { } _EXPORT_STD template -_NODISCARD constexpr auto cbegin(const _Container& _Cont) - noexcept(noexcept(_STD begin(_Cont))) -> decltype(_STD begin(_Cont)) { +_NODISCARD constexpr auto cbegin(const _Container& _Cont) noexcept(noexcept(_STD begin(_Cont))) + -> decltype(_STD begin(_Cont)) { return _STD begin(_Cont); } _EXPORT_STD template -_NODISCARD constexpr auto cend(const _Container& _Cont) - noexcept(noexcept(_STD end(_Cont))) -> decltype(_STD end(_Cont)) { +_NODISCARD constexpr auto cend(const _Container& _Cont) noexcept(noexcept(_STD end(_Cont))) + -> decltype(_STD end(_Cont)) { return _STD end(_Cont); } @@ -2893,7 +2893,7 @@ namespace ranges { template _NODISCARD _MSVC_INTRINSIC constexpr auto& _Possibly_const_range(_Rng& _Range) noexcept { - if constexpr (constant_range && !constant_range<_Rng>) { + if constexpr (input_range) { return _STD as_const(_Range); } else { return _Range; @@ -4123,10 +4123,9 @@ namespace ranges { subrange(_It, _Se, _Make_unsigned_like_t>) -> subrange<_It, _Se, subrange_kind::sized>; template - subrange(_Rng&&) - -> subrange, sentinel_t<_Rng>, - (sized_range<_Rng> || sized_sentinel_for, iterator_t<_Rng>>) ? subrange_kind::sized - : subrange_kind::unsized>; + subrange(_Rng&&) -> subrange, sentinel_t<_Rng>, + (sized_range<_Rng> || sized_sentinel_for, iterator_t<_Rng>>) ? subrange_kind::sized + : subrange_kind::unsized>; template subrange(_Rng&&, _Make_unsigned_like_t>) diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index c5df1123c6b..95e70c0cd59 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -80,6 +80,8 @@ // (__cpp_lib_freestanding_algorithm and __cpp_lib_freestanding_array only) // P2937R0 Freestanding Library: Remove strtok // P2968R2 Make std::ignore A First-Class Object +// P3323R1 Forbid atomic, Specify atomic_ref +// (for atomic) // _HAS_CXX17 directly controls: // P0005R4 not_fn() @@ -314,6 +316,9 @@ // P2905R2 Runtime Format Strings // P2909R4 Fix Formatting Of Code Units As Integers // P2997R1 Removing The Common Reference Requirement From The Indirectly Invocable Concepts +// P3136R1 Retiring Niebloids +// P3323R1 Forbid atomic, Specify atomic_ref +// (for atomic_ref) // _HAS_CXX20 indirectly controls: // P0619R4 Removing C++17-Deprecated Features @@ -916,7 +921,7 @@ #define _CPPLIB_VER 650 #define _MSVC_STL_VERSION 143 -#define _MSVC_STL_UPDATE 202412L +#define _MSVC_STL_UPDATE 202501L #ifndef _ALLOW_COMPILER_AND_STL_VERSION_MISMATCH #if defined(__CUDACC__) && defined(__CUDACC_VER_MAJOR__) @@ -926,8 +931,8 @@ _EMIT_STL_ERROR(STL1002, "Unexpected compiler version, expected CUDA 12.4 or new #elif defined(__EDG__) // not attempting to detect __EDG_VERSION__ being less than expected #elif defined(__clang__) -#if __clang_major__ < 18 -_EMIT_STL_ERROR(STL1000, "Unexpected compiler version, expected Clang 18.0.0 or newer."); +#if __clang_major__ < 19 +_EMIT_STL_ERROR(STL1000, "Unexpected compiler version, expected Clang 19.0.0 or newer."); #endif // ^^^ old Clang ^^^ #elif defined(_MSC_VER) #if _MSC_VER < 1942 // Coarse-grained, not inspecting _MSC_FULL_VER @@ -1518,7 +1523,17 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #define _CXX20_DEPRECATE_CODECVT_CHAR8_T_FACETS #endif // ^^^ warning disabled ^^^ -// next warning number: STL4048 +#if !defined(_SILENCE_LOCALE_EMPTY_DEPRECATION_WARNING) && !defined(_SILENCE_ALL_MS_EXT_DEPRECATION_WARNINGS) +#define _DEPRECATE_LOCALE_EMPTY \ + [[deprecated( \ + "warning STL4048: locale::empty() is a non-Standard extension and will be removed in the future. A " \ + "default-constructed locale can be used instead. You can define _SILENCE_LOCALE_EMPTY_DEPRECATION_WARNING or " \ + "_SILENCE_ALL_MS_EXT_DEPRECATION_WARNINGS to suppress this warning.")]] +#else // ^^^ warning enabled / warning disabled vvv +#define _DEPRECATE_LOCALE_EMPTY +#endif // ^^^ warning disabled ^^^ + +// next warning number: STL4049 // next error number: STL1006 diff --git a/stl/src/excptptr.cpp b/stl/src/excptptr.cpp index 830cb65a940..e866980fb1d 100644 --- a/stl/src/excptptr.cpp +++ b/stl/src/excptptr.cpp @@ -505,8 +505,10 @@ _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCurrentException(void* // Alloc memory on stack for exception object. This might cause a stack overflow SEH exception, or another C++ // exception when copying the C++ exception object. In that case, we just let that become the thrown exception. -#pragma warning(suppress : 6255) // _alloca indicates failure by raising a stack overflow exception +#pragma warning(push) +#pragma warning(disable : 6255) // _alloca indicates failure by raising a stack overflow exception void* _PExceptionBuffer = alloca(_PType->sizeOrOffset); +#pragma warning(pop) _CopyExceptionObject(_PExceptionBuffer, _CppRecord.params.pExceptionObject, _PType #if _EH_RELATIVE_TYPEINFO , diff --git a/stl/src/locale.cpp b/stl/src/locale.cpp index 8dc8f4a1f07..e11e106f16f 100644 --- a/stl/src/locale.cpp +++ b/stl/src/locale.cpp @@ -124,8 +124,10 @@ void __CLRCALL_PURE_OR_CDECL locale::_Locimp::_Locimp_Addfac( } } ptrfac->_Incref(); -#pragma warning(suppress : 6001) // PREfast isn't following through _realloc_crt here +#pragma warning(push) +#pragma warning(disable : 6001) // PREfast isn't following through _realloc_crt here if (_This->_Facetvec[id] != nullptr) { +#pragma warning(pop) delete _This->_Facetvec[id]->_Decref(); } diff --git a/stl/src/locale0.cpp b/stl/src/locale0.cpp index 032dbb2d982..81aae0ad22e 100644 --- a/stl/src/locale0.cpp +++ b/stl/src/locale0.cpp @@ -9,6 +9,8 @@ #undef _ENFORCE_ONLY_CORE_HEADERS // TRANSITION, should be a core header +#define _SILENCE_LOCALE_EMPTY_DEPRECATION_WARNING + #include #include #include diff --git a/stl/src/multprec.cpp b/stl/src/multprec.cpp index 6236e33b624..0043cfbfb96 100644 --- a/stl/src/multprec.cpp +++ b/stl/src/multprec.cpp @@ -134,8 +134,10 @@ void __CLRCALL_PURE_OR_CDECL _MP_Rem( unsigned long long rh = ((u[j + n] << shift) + u[j + n - 1]) % v[n - 1]; for (;;) { -#pragma warning(suppress : 6385) // TRANSITION, GH-1008 +#pragma warning(push) +#pragma warning(disable : 6385) // TRANSITION, GH-1008 if (qh < maxVal && qh * v[n - 2] <= (rh << shift) + u[j + n - 2]) { +#pragma warning(pop) break; } else { // reduce tentative value and retry --qh; diff --git a/stl/src/xstoul.cpp b/stl/src/xstoul.cpp index 50789659027..02db3d9394f 100644 --- a/stl/src/xstoul.cpp +++ b/stl/src/xstoul.cpp @@ -71,7 +71,7 @@ _CRTIMP2_PURE unsigned long __CLRCALL_PURE_OR_CDECL _Stoulx( x = 0; for (s2 = sc, y = 0; (sd = static_cast(memchr(&digits[0], tolower(*sc), base))) != nullptr; - ++sc) { // accumulate digits + ++sc) { // accumulate digits y = x; dig = static_cast(sd - digits); // for overflow checking x = x * base + dig; diff --git a/stl/src/xstoull.cpp b/stl/src/xstoull.cpp index 5d058e9d025..88aff9b076c 100644 --- a/stl/src/xstoull.cpp +++ b/stl/src/xstoull.cpp @@ -69,7 +69,7 @@ _CRTIMP2_PURE unsigned long long __CLRCALL_PURE_OR_CDECL _Stoullx( x = 0; for (s2 = sc, y = 0, dig = 0; (sd = static_cast(memchr(&digits[0], tolower(*sc), base))) != nullptr; - ++sc) { // accumulate digits + ++sc) { // accumulate digits y = x; dig = static_cast(sd - digits); // for overflow checking x = x * base + dig; diff --git a/stl/src/xwcsxfrm.cpp b/stl/src/xwcsxfrm.cpp index 417545e1f85..f3a2300dac3 100644 --- a/stl/src/xwcsxfrm.cpp +++ b/stl/src/xwcsxfrm.cpp @@ -73,9 +73,11 @@ _CRTIMP2_PURE size_t __CLRCALL_PURE_OR_CDECL _Wcsxfrm(_Out_writes_(end1 - string auto bbuffer = _malloc_crt_t(unsigned char, n1); if (bbuffer) { -#pragma warning(suppress : 6386) // PREfast doesn't understand LCMAP_SORTKEY +#pragma warning(push) +#pragma warning(disable : 6386) // PREfast doesn't understand LCMAP_SORTKEY size = __crtLCMapStringW(locale_name, LCMAP_SORTKEY, string2, static_cast(n2), reinterpret_cast(bbuffer.get()), static_cast(n1)); +#pragma warning(pop) if (size == 0) { // buffer not big enough, get size required. diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 980ddcf194b..51c1dbae1f5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -34,3 +34,4 @@ get_property(STL_LIT_TEST_DIRS GLOBAL PROPERTY STL_LIT_TEST_DIRS) add_custom_target(STL-CI COMMAND ${STL_LIT_COMMAND} -Dnotags=ASAN ${STL_LIT_TEST_DIRS} USES_TERMINAL) add_custom_target(STL-ASan-CI COMMAND ${STL_LIT_COMMAND} -Dtags=ASAN ${STL_LIT_TEST_DIRS} USES_TERMINAL) +add_custom_target(test-only-edg COMMAND ${STL_LIT_COMMAND} -Dnotags=ASAN -Dtest-only-edg=True --xunit-xml-output test-results.xml ${STL_LIT_TEST_DIRS} USES_TERMINAL) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 3329d34b8f1..8f987d07f5e 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -36,11 +36,13 @@ std/numerics/rand/rand.dist/rand.dist.uni/rand.dist.uni.real/param_ctor.pass.cpp # LLVM-113609: [libc++][test] Non-rebindable test_alloc in string.capacity/deallocate_size.pass.cpp std/strings/basic.string/string.capacity/deallocate_size.pass.cpp FAIL -# LLVM-119174: [libcxx][test] Silence nodiscard warnings for std::expected -std/utilities/expected/expected.expected/monadic/and_then.pass.cpp FAIL -std/utilities/expected/expected.expected/monadic/or_else.pass.cpp FAIL -std/utilities/expected/expected.expected/monadic/transform.pass.cpp FAIL -std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp FAIL +# LLVM-116054: [libc++] vprint_[non]unicode(ostream &, string_view, Args&&...) should not pad the output +std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/print.pass.cpp FAIL +std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_nonunicode.pass.cpp FAIL +std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_unicode.pass.cpp FAIL + +# LLVM-122638: [libc++][test] re.regex.construct/bad_backref.pass.cpp assumes non-standard extension to extended regular expressions +std/re/re.regex/re.regex.construct/bad_backref.pass.cpp FAIL # Non-Standard regex behavior. # "It seems likely that the test is still non-conforming due to how libc++ handles the 'w' character class." @@ -126,6 +128,9 @@ std/language.support/support.limits/support.limits.general/mdspan.version.compil # libc++ has not implemented P2937R0: "Freestanding Library: Remove strtok" std/language.support/support.limits/support.limits.general/cstring.version.compile.pass.cpp FAIL +# libc++ has not implemented P3323R1: "Forbid atomic, Specify atomic_ref" +std/atomics/atomics.ref/member_types.compile.pass.cpp FAIL + # Various bogosity (LLVM-D141004), warning C6011: Dereferencing NULL pointer # Note: The :1 (ASan) configuration doesn't run static analysis. std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp:0 FAIL @@ -151,6 +156,9 @@ std/language.support/support.limits/support.limits.general/ranges.version.compil # libc++ is missing various DRs std/language.support/support.limits/support.limits.general/format.version.compile.pass.cpp FAIL +# libc++ doesn't implement LWG-2584 (LLVM-99976) +std/re/re.regex/re.regex.construct/bad_escape.pass.cpp FAIL + # libc++ doesn't implement LWG-3670 std/ranges/range.factories/range.iota.view/iterator/member_typedefs.compile.pass.cpp FAIL @@ -165,7 +173,7 @@ std/ranges/range.adaptors/range.join/range.join.iterator/arrow.pass.cpp FAIL std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp FAIL -# *** INTERACTIONS WITH CONTEST / C1XX THAT UPSTREAM LIKELY WON'T FIX *** +# *** INTERACTIONS WITH MSVC THAT UPSTREAM LIKELY WON'T FIX *** # These tests set an allocator with a max_size() too small to default construct an unordered container # (due to our minimum bucket size). std/containers/unord/unord.map/max_size.pass.cpp FAIL @@ -217,6 +225,92 @@ std/input.output/syncstream/osyncstream/thread/several_threads.pass.cpp:1 SKIPPE std/depr/depr.c.headers/uchar_h.compile.pass.cpp FAIL std/strings/c.strings/cuchar.compile.pass.cpp FAIL +# P0429R9 +# FIXME! Investigate these failures before merging! +std/containers/container.adaptors/flat.map/flat.map.access/at_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.access/at.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.access/index_key.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.access/index_rv_key.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.capacity/empty.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.capacity/size.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/assign_initializer_list.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/compare.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/containers.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/copy_alloc.pass.cpp:0 SKIPPED +std/containers/container.adaptors/flat.map/flat.map.cons/copy_alloc.pass.cpp:1 SKIPPED +std/containers/container.adaptors/flat.map/flat.map.cons/copy_assign.addressof.compile.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/copy_assign.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/copy.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/deduct_pmr.pass.cpp:0 FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/deduct_pmr.pass.cpp:1 FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/deduct.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/initializer_list.pass.cpp:0 FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/initializer_list.pass.cpp:1 FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/move_alloc.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/move_assign_clears.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/move_assign_noexcept.pass.cpp:2 FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/move_assign.pass.cpp:0 FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/move_assign.pass.cpp:1 FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/move_exceptions.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/move.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/pmr.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/range.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/sorted_container.pass.cpp:0 FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/sorted_container.pass.cpp:1 FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/sorted_initializer_list.pass.cpp:0 FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/sorted_initializer_list.pass.cpp:1 FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/sorted_iter_iter.pass.cpp:0 FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/sorted_iter_iter.pass.cpp:1 FAIL +std/containers/container.adaptors/flat.map/flat.map.erasure/erase_if_exceptions.pass.cpp:2 FAIL +std/containers/container.adaptors/flat.map/flat.map.erasure/erase_if.pass.cpp:0 SKIPPED +std/containers/container.adaptors/flat.map/flat.map.erasure/erase_if.pass.cpp:1 SKIPPED +std/containers/container.adaptors/flat.map/flat.map.iterators/iterator_comparison.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.iterators/iterator_concept_conformance.compile.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.iterators/iterator.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.iterators/range_concept_conformance.compile.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/clear.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/emplace_hint.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/emplace.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_iter_iter.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_iter.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_key_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_key.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/extract.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_cv.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_initializer_list.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_iter_cv.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_iter_iter.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_iter_rv.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_or_assign_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_or_assign.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_range.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_rv.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_sorted_initializer_list.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_sorted_iter_iter.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/replace.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_free.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_member.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/try_emplace_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/try_emplace.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.observers/keys_values.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/contains_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/contains.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/count_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/count.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/equal_range_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/equal_range.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/find_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/find.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/lower_bound_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/lower_bound.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/upper_bound_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/upper_bound.pass.cpp FAIL +std/containers/container.adaptors/flat.map/incomplete_type.pass.cpp FAIL +std/containers/container.adaptors/flat.map/op_compare.pass.cpp FAIL + # P0533R9 constexpr For And std/language.support/support.limits/support.limits.general/cmath.version.compile.pass.cpp FAIL std/language.support/support.limits/support.limits.general/cstdlib.version.compile.pass.cpp FAIL @@ -240,8 +334,10 @@ std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/ctad. # *** MISSING LWG ISSUE RESOLUTIONS *** # LWG-2503 "multiline option should be added to syntax_option_type" +std/re/re.alg/re.alg.search/no_update_pos.pass.cpp FAIL std/re/re.const/re.matchflag/match_multiline.pass.cpp FAIL std/re/re.const/re.matchflag/match_not_eol.pass.cpp FAIL +std/re/re.const/re.synopt/syntax_option_type.pass.cpp FAIL # LWG-2532 "Satisfying a promise at thread exit" (Open) # WCFB02 implements the proposed resolution for this issue @@ -331,24 +427,78 @@ std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp:1 FAIL std/language.support/support.rtti/type.info/type_info.equal.pass.cpp:0 FAIL std/language.support/support.rtti/type.info/type_info.equal.pass.cpp:1 FAIL +# DevCom-10808176 VSO-2319111 MSVC doesn't properly destroy a loop variable in constant evaluation +# Fixed in VS 2022 17.14 Preview 1. +std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp:0 FAIL +std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp:1 FAIL +std/containers/sequences/vector.bool/construct_iter_iter.pass.cpp:0 FAIL +std/containers/sequences/vector.bool/construct_iter_iter.pass.cpp:1 FAIL +std/containers/sequences/vector.bool/construct_iter_iter_alloc.pass.cpp:0 FAIL +std/containers/sequences/vector.bool/construct_iter_iter_alloc.pass.cpp:1 FAIL +std/containers/sequences/vector.bool/construct_size.pass.cpp:0 FAIL +std/containers/sequences/vector.bool/construct_size.pass.cpp:1 FAIL +std/containers/sequences/vector.bool/construct_size_value.pass.cpp:0 FAIL +std/containers/sequences/vector.bool/construct_size_value.pass.cpp:1 FAIL +std/containers/sequences/vector.bool/construct_size_value_alloc.pass.cpp:0 FAIL +std/containers/sequences/vector.bool/construct_size_value_alloc.pass.cpp:1 FAIL +std/containers/sequences/vector/reverse_iterators.pass.cpp:0 FAIL +std/containers/sequences/vector/reverse_iterators.pass.cpp:1 FAIL +std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp:0 FAIL +std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp:1 FAIL +std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp:0 FAIL +std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp:1 FAIL +std/containers/sequences/vector/vector.cons/construct_size.pass.cpp:0 FAIL +std/containers/sequences/vector/vector.cons/construct_size.pass.cpp:1 FAIL +std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp:0 FAIL +std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp:1 FAIL +std/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp:0 FAIL +std/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp:1 FAIL +std/containers/views/mdspan/mdspan/index_operator.pass.cpp:0 FAIL +std/containers/views/mdspan/mdspan/index_operator.pass.cpp:1 FAIL + +# VSO-2338829 constexpr error "subtracting pointers to elements of different arrays" in _String_const_iterator::_Verify_offset() +std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp:1 FAIL + +# VSO-2338880 constexpr error in vector::iterator's _Compat() check when using views::transform +std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp:0 FAIL +std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp:1 FAIL +std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.segmented.pass.cpp:0 FAIL +std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.segmented.pass.cpp:1 FAIL +std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_n.segmented.pass.cpp:0 FAIL +std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_n.segmented.pass.cpp:1 FAIL +std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp:0 FAIL +std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp:1 FAIL +std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.segmented.pass.cpp:0 FAIL +std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.segmented.pass.cpp:1 FAIL +std/algorithms/alg.modifying.operations/alg.move/ranges.move.segmented.pass.cpp:0 FAIL +std/algorithms/alg.modifying.operations/alg.move/ranges.move.segmented.pass.cpp:1 FAIL + # *** CLANG COMPILER BUGS *** # LLVM-46207 Clang's tgmath.h interferes with the UCRT's tgmath.h std/depr/depr.c.headers/tgmath_h.pass.cpp:2 FAIL -# LLVM-95311 [clang] __has_unique_object_representations gives inconsistent answer based on instantiation order -# A libc++ product code workaround (using `remove_all_extents_t`) and test coverage were added by LLVM-95314. -# Fixed by LLVM-95432 in Clang 19. -std/utilities/meta/meta.unary/meta.unary.prop/has_unique_object_representations.compile.pass.cpp:2 FAIL - # *** CLANG ISSUES, NOT YET ANALYZED *** -# Clang doesn't enable sized deallocation by default. Should we add -fsized-deallocation or do something else? -std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_fsizeddeallocation.pass.cpp:2 SKIPPED -std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array14.pass.cpp:2 SKIPPED -std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.pass.cpp:2 SKIPPED -std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete14.pass.cpp:2 SKIPPED - # Not analyzed. Clang apparently defines platform macros differently from C1XX. std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp:2 FAIL @@ -438,6 +588,7 @@ std/input.output/syncstream/syncbuf/syncstream.syncbuf.members/emit.pass.cpp FAI # *** VCRUNTIME BUGS *** # DevCom-10373274 VSO-1824997 "vcruntime nothrow array operator new falls back on the wrong function" # This passes for the :1 (ASan) configuration, surprisingly. +# Fixed in VS 2022 17.14 Preview 1. std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.indirect.pass.cpp:0 FAIL std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.indirect.pass.cpp:2 FAIL @@ -548,9 +699,34 @@ std/utilities/memory/pointer.conversion/to_address_without_pointer_traits.pass.c # We disagree about whether various chrono types should be optimized, and the test is clearly wrong about vector::reference. std/utilities/format/format.formatter/format.formatter.locking/enable_nonlocking_formatter_optimization.compile.pass.cpp FAIL -# `increasing_allocator` calls `std::allocator::deallocate` with the wrong size -std/containers/sequences/vector.bool/shrink_to_fit.pass.cpp FAIL -std/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp FAIL +# We disagree on the syntax flags set by the default basic_regex constructor: we set 0, libc++ sets ECMAScript. +# Relates to LWG-3604. +std/re/re.regex/re.regex.construct/default.pass.cpp FAIL +std/re/re.regex/re.regex.nonmemb/re.regex.nmswap/swap.pass.cpp FAIL +std/re/re.regex/re.regex.swap/swap.pass.cpp FAIL + +# Test emits a Clang -Wself-move warning, so it should avoid the self-move or suppress the warning. +std/containers/sequences/vector/addressof.compile.pass.cpp:2 FAIL + +# throwing_allocator appears to be totally non-Standard. +std/containers/sequences/vector.bool/ctor_exceptions.pass.cpp FAIL + +# The test is checking _LIBCPP_HAS_THREADS, which we don't have. +std/language.support/support.limits/support.limits.general/shared_mutex.version.compile.pass.cpp FAIL + +# x64 truncation warnings caused by allocators. +std/containers/sequences/vector/vector.capacity/reserve_exceptions.pass.cpp:0 SKIPPED +std/containers/sequences/vector/vector.capacity/reserve_exceptions.pass.cpp:1 SKIPPED +std/containers/sequences/vector/vector.capacity/resize_size_exceptions.pass.cpp:0 SKIPPED +std/containers/sequences/vector/vector.capacity/resize_size_exceptions.pass.cpp:1 SKIPPED +std/containers/sequences/vector/vector.capacity/resize_size_value_exceptions.pass.cpp:0 SKIPPED +std/containers/sequences/vector/vector.capacity/resize_size_value_exceptions.pass.cpp:1 SKIPPED + +# Instantiating istreambuf_iterator requires _Traits to be complete. +# However, when only is included, char_traits is merely forward-declared in our implementation. +# The definition of char_traits isn't required to be provided by , so this test appears to be bogus. +# error: incomplete type 'std::char_traits' named in nested name specifier +std/iterators/iterator.requirements/iterator.assoc.types/readable.traits/indirectly_readable_traits.compile.pass.cpp FAIL # *** LIKELY STL BUGS *** @@ -563,13 +739,6 @@ std/re/re.alg/re.alg.search/awk.pass.cpp FAIL std/re/re.alg/re.alg.search/basic.pass.cpp FAIL std/re/re.alg/re.alg.search/ecma.pass.cpp FAIL std/re/re.alg/re.alg.search/extended.pass.cpp FAIL -std/re/re.alg/re.alg.search/no_update_pos.pass.cpp FAIL -std/re/re.const/re.synopt/syntax_option_type.pass.cpp FAIL -std/re/re.regex/re.regex.construct/bad_backref.pass.cpp FAIL -std/re/re.regex/re.regex.construct/bad_escape.pass.cpp FAIL -std/re/re.regex/re.regex.construct/default.pass.cpp FAIL -std/re/re.regex/re.regex.nonmemb/re.regex.nmswap/swap.pass.cpp FAIL -std/re/re.regex/re.regex.swap/swap.pass.cpp FAIL std/re/re.traits/lookup_collatename.pass.cpp FAIL std/re/re.traits/transform_primary.pass.cpp FAIL @@ -776,35 +945,6 @@ std/algorithms/algorithms.results/min_max_result.pass.cpp:1 FAIL # Not analyzed. std/algorithms/robust_against_proxy_iterators_lifetime_bugs.pass.cpp FAIL -# Not analyzed. Possible MSVC constexpr bug. -# note: failure was caused by a read of a variable outside its lifetime -std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp:0 FAIL -std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp:1 FAIL -std/containers/sequences/vector.bool/construct_iter_iter.pass.cpp:0 FAIL -std/containers/sequences/vector.bool/construct_iter_iter.pass.cpp:1 FAIL -std/containers/sequences/vector.bool/construct_iter_iter_alloc.pass.cpp:0 FAIL -std/containers/sequences/vector.bool/construct_iter_iter_alloc.pass.cpp:1 FAIL -std/containers/sequences/vector.bool/construct_size.pass.cpp:0 FAIL -std/containers/sequences/vector.bool/construct_size.pass.cpp:1 FAIL -std/containers/sequences/vector.bool/construct_size_value.pass.cpp:0 FAIL -std/containers/sequences/vector.bool/construct_size_value.pass.cpp:1 FAIL -std/containers/sequences/vector.bool/construct_size_value_alloc.pass.cpp:0 FAIL -std/containers/sequences/vector.bool/construct_size_value_alloc.pass.cpp:1 FAIL -std/containers/sequences/vector/reverse_iterators.pass.cpp:0 FAIL -std/containers/sequences/vector/reverse_iterators.pass.cpp:1 FAIL -std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp:0 FAIL -std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp:1 FAIL -std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp:0 FAIL -std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp:1 FAIL -std/containers/sequences/vector/vector.cons/construct_size.pass.cpp:0 FAIL -std/containers/sequences/vector/vector.cons/construct_size.pass.cpp:1 FAIL -std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp:0 FAIL -std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp:1 FAIL -std/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp:0 FAIL -std/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp:1 FAIL -std/containers/views/mdspan/mdspan/index_operator.pass.cpp:0 FAIL -std/containers/views/mdspan/mdspan/index_operator.pass.cpp:1 FAIL - # Not analyzed. Looks like a test bug, assuming that hash> is constexpr. std/containers/sequences/vector.bool/enabled_hash.pass.cpp FAIL std/containers/sequences/vector.bool/vector_bool.pass.cpp FAIL @@ -836,28 +976,6 @@ std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/iter_swap.pass # Clang error: non-type template argument is not a constant expression std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_const_move.pass.cpp FAIL -# Not analyzed, probably MSVC constexpr issue(s) -std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp:1 FAIL - # Not analyzed, possible path length issue. With a repo root of D:\GitHub\STL (13 characters), fails with: # "error RC2136 : missing '=' in EXSTYLE=" followed by "LINK : fatal error LNK1327: failure during running rc.exe" std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until_deadlock_bug.pass.cpp SKIPPED @@ -871,6 +989,7 @@ std/algorithms/alg.nonmodifying/alg.count/count.pass.cpp FAIL std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp FAIL std/containers/sequences/vector.bool/append_range.pass.cpp FAIL std/containers/sequences/vector.bool/assign_range.pass.cpp FAIL +std/containers/sequences/vector.bool/flip.pass.cpp FAIL std/containers/sequences/vector.bool/insert_range.pass.cpp FAIL std/containers/sequences/vector/vector.modifiers/destroy_elements.pass.cpp FAIL std/containers/sequences/vector/vector.modifiers/insert_range.pass.cpp FAIL @@ -960,20 +1079,6 @@ std/time/time.syn/formatter.local_time.pass.cpp:2 FAIL std/time/time.syn/formatter.sys_time.pass.cpp:2 FAIL std/time/time.syn/formatter.zoned_time.pass.cpp:2 FAIL -# Not analyzed. constexpr evaluation fails with "vector iterators incompatible". -std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp:0 FAIL -std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp:1 FAIL -std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.segmented.pass.cpp:0 FAIL -std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.segmented.pass.cpp:1 FAIL -std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_n.segmented.pass.cpp:0 FAIL -std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_n.segmented.pass.cpp:1 FAIL -std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp:0 FAIL -std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp:1 FAIL -std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.segmented.pass.cpp:0 FAIL -std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.segmented.pass.cpp:1 FAIL -std/algorithms/alg.modifying.operations/alg.move/ranges.move.segmented.pass.cpp:0 FAIL -std/algorithms/alg.modifying.operations/alg.move/ranges.move.segmented.pass.cpp:1 FAIL - # Not analyzed. constexpr evaluation fails with note: failure was caused by out of range index MEOW; allowed range is 0 <= index < 2 std/ranges/range.adaptors/range.join/adaptor.pass.cpp:0 FAIL std/ranges/range.adaptors/range.join/adaptor.pass.cpp:1 FAIL @@ -1068,6 +1173,7 @@ std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/recursion_pen std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp SKIPPED std/input.output/filesystems/fs.op.funcs/fs.op.absolute/absolute.pass.cpp SKIPPED std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp SKIPPED +std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file_procfs.pass.cpp SKIPPED std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp SKIPPED std/input.output/filesystems/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp SKIPPED std/input.output/filesystems/fs.op.funcs/fs.op.copy/copy.pass.cpp SKIPPED @@ -1112,11 +1218,6 @@ std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical # Clang error: unknown attribute 'no_unique_address' ignored [-Werror,-Wunknown-attributes] std/ranges/ranges_robust_against_no_unique_address.pass.cpp FAIL -# Not analyzed. Runtime assertion, we appear to be ignoring stream width. -std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/print.pass.cpp FAIL -std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_nonunicode.pass.cpp FAIL -std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_unicode.pass.cpp FAIL - # Not analyzed. test_chrono_leap_second.h wants us to provide a vendor-specific version of # test_leap_second_create(), but it's unclear how to adapt their parameters to our implementation. std/time/time.zone/time.zone.leap/assign.copy.pass.cpp FAIL @@ -1185,6 +1286,14 @@ std/numerics/c.math/hermite.pass.cpp FAIL # Not analyzed. Test coverage for LLVM-104496 uses span. std/containers/views/views.span/span.cons/copy.pass.cpp FAIL +# Not analyzed. These tests disable or limit allocations, which interferes with our proxy objects. +std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp FAIL +std/containers/sequences/vector/vector.capacity/shrink_to_fit_exceptions.pass.cpp FAIL + +# Not analyzed. Our stdalign.h doesn't define __alignas_is_defined in C++ mode. +std/depr/depr.c.headers/stdalign_h.compile.pass.cpp:0 FAIL +std/depr/depr.c.headers/stdalign_h.compile.pass.cpp:1 FAIL + # *** XFAILS WHICH PASS *** # These tests contain `// XFAIL: msvc` comments, which accurately describe runtime failures for x86 and x64. @@ -1228,6 +1337,14 @@ std/algorithms/alg.nonmodifying/alg.equal/equal.pass.cpp:9 SKIPPED std/algorithms/alg.nonmodifying/alg.find/find.pass.cpp:9 SKIPPED std/algorithms/alg.nonmodifying/alg.find/ranges.find.pass.cpp:9 SKIPPED std/algorithms/alg.nonmodifying/alg.fold/left_folds.pass.cpp:9 SKIPPED +std/containers/associative/map/map.modifiers/insert_range.pass.cpp:9 SKIPPED +std/containers/associative/multimap/multimap.modifiers/insert_range.pass.cpp:9 SKIPPED +std/containers/associative/multiset/insert_range.pass.cpp:9 SKIPPED +std/containers/associative/set/insert_range.pass.cpp:9 SKIPPED +std/containers/unord/unord.map/unord.map.modifiers/insert_range.pass.cpp:9 SKIPPED +std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_range.pass.cpp:9 SKIPPED +std/containers/unord/unord.multiset/insert_range.pass.cpp:9 SKIPPED +std/containers/unord/unord.set/insert_range.pass.cpp:9 SKIPPED std/depr/depr.c.headers/setjmp_h.compile.pass.cpp:9 SKIPPED std/input.output/file.streams/fstreams/ifstream.members/buffered_reads.pass.cpp:9 SKIPPED std/input.output/file.streams/fstreams/ofstream.members/buffered_writes.pass.cpp:9 SKIPPED @@ -1238,17 +1355,6 @@ std/ranges/range.utility/range.utility.conv/to.pass.cpp:9 SKIPPED std/thread/thread.jthread/assign.move.pass.cpp:9 SKIPPED std/utilities/meta/meta.unary/dependent_return_type.compile.pass.cpp:9 SKIPPED -# These tests also need ADDITIONAL_COMPILE_FLAGS to silence warnings, but only for Clang 18. -# TRANSITION, Clang 19 -std/containers/associative/map/map.modifiers/insert_range.pass.cpp:9 SKIPPED -std/containers/associative/multimap/multimap.modifiers/insert_range.pass.cpp:9 SKIPPED -std/containers/associative/multiset/insert_range.pass.cpp:9 SKIPPED -std/containers/associative/set/insert_range.pass.cpp:9 SKIPPED -std/containers/unord/unord.map/unord.map.modifiers/insert_range.pass.cpp:9 SKIPPED -std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_range.pass.cpp:9 SKIPPED -std/containers/unord/unord.multiset/insert_range.pass.cpp:9 SKIPPED -std/containers/unord/unord.set/insert_range.pass.cpp:9 SKIPPED - # This test is marked as `XFAIL: msvc`, but the MSVC-internal test harness doesn't yet parse XFAIL. std/utilities/function.objects/func.wrap/func.wrap.func/noncopyable_return_type.pass.cpp:9 SKIPPED @@ -1270,3 +1376,7 @@ std/iterators/iterator.container/ssize.LWG3207.compile.pass.cpp:9 SKIPPED # This test is marked as `REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators-in-vector`. # Listing these on separate lines would allow magic_comments.txt to recognize it. std/containers/sequences/vector/vector.modifiers/assert.push_back.invalidation.pass.cpp:9 SKIPPED + +# This test is marked as `REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators-in-std-array`. +# Listing these on separate lines would allow magic_comments.txt to recognize it. +std/containers/sequences/array/assert.iterators.pass.cpp:9 SKIPPED diff --git a/tests/std/include/instantiate_algorithms_op_deref.hpp b/tests/std/include/instantiate_algorithms_op_deref.hpp index 43ab47a2a4e..1d5a22656e8 100644 --- a/tests/std/include/instantiate_algorithms_op_deref.hpp +++ b/tests/std/include/instantiate_algorithms_op_deref.hpp @@ -333,7 +333,9 @@ void test_optional() { const optional oe{Evil()}; (void) oe.value(); } - { (void) optional{Evil()}.value(); } + { + (void) optional{Evil()}.value(); + } { using T = const optional; (void) T{Evil()}.value(); diff --git a/tests/std/include/range_algorithm_support.hpp b/tests/std/include/range_algorithm_support.hpp index 056b84b2982..96b44d2616a 100644 --- a/tests/std/include/range_algorithm_support.hpp +++ b/tests/std/include/range_algorithm_support.hpp @@ -964,7 +964,12 @@ namespace test { requires std::signed_integral && requires { typename std::iterator_traits::iterator_category; } struct redifference_iterator_category_base { using iterator_category = std::iterator_traits::iterator_category; - using iterator_concept = decltype([] { + }; + + template + class redifference_iterator : public redifference_iterator_category_base { + public: + using iterator_concept = decltype([] { if constexpr (std::contiguous_iterator) { return std::contiguous_iterator_tag{}; } else if constexpr (std::random_access_iterator) { @@ -977,13 +982,8 @@ namespace test { return std::input_iterator_tag{}; } }()); - }; - - template - class redifference_iterator : public redifference_iterator_category_base { - public: - using value_type = std::iter_value_t; - using difference_type = Diff; + using value_type = std::iter_value_t; + using difference_type = Diff; redifference_iterator() = default; constexpr explicit redifference_iterator(It it) : i_{std::move(it)} {} @@ -1052,22 +1052,22 @@ namespace test { return i.i_ == j.i_; } - [[nodiscard]] friend constexpr redifference_iterator operator+( - const redifference_iterator& it, std::same_as auto n) + template I> // TRANSITION, DevCom-10735214, should be abbreviated + [[nodiscard]] friend constexpr redifference_iterator operator+(const redifference_iterator& it, I n) requires std::random_access_iterator { return redifference_iterator{it.i_ + static_cast>(n)}; } - [[nodiscard]] friend constexpr redifference_iterator operator+( - std::same_as auto n, const redifference_iterator& it) + template I> // TRANSITION, DevCom-10735214, should be abbreviated + [[nodiscard]] friend constexpr redifference_iterator operator+(I n, const redifference_iterator& it) requires std::random_access_iterator { return redifference_iterator{it.i_ + static_cast>(n)}; } - [[nodiscard]] friend constexpr redifference_iterator operator-( - const redifference_iterator& it, std::same_as auto n) + template I> // TRANSITION, DevCom-10735214, should be abbreviated + [[nodiscard]] friend constexpr redifference_iterator operator-(const redifference_iterator& it, I n) requires std::random_access_iterator { return redifference_iterator{it.i_ - static_cast>(n)}; diff --git a/tests/std/test.lst b/tests/std/test.lst index 15d320dc105..3dfff6506c1 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -640,6 +640,7 @@ tests\P2286R8_text_formatting_range_map tests\P2286R8_text_formatting_range_sequence tests\P2286R8_text_formatting_range_set tests\P2286R8_text_formatting_range_string +tests\P2286R8_text_formatting_range_string_death tests\P2286R8_text_formatting_tuple tests\P2286R8_text_formatting_tuple_disambiguation tests\P2286R8_text_formatting_vector_bool_reference diff --git a/tests/std/tests/Dev08_563686_ostream/test.cpp b/tests/std/tests/Dev08_563686_ostream/test.cpp index 11d905320fd..73b7cc3cca5 100644 --- a/tests/std/tests/Dev08_563686_ostream/test.cpp +++ b/tests/std/tests/Dev08_563686_ostream/test.cpp @@ -49,7 +49,9 @@ int main() { _CrtMemCheckpoint(&before); // Construct and destroy an iostream, which previously leaked. - { std::iostream s(nullptr); } + { + std::iostream s(nullptr); + } // Get memory state after iostream allocation/deallocation _CrtMemState after; diff --git a/tests/std/tests/Dev09_126254_persistent_aux_allocators/test.cpp b/tests/std/tests/Dev09_126254_persistent_aux_allocators/test.cpp index b8f0fa0309a..4d9f52562ba 100644 --- a/tests/std/tests/Dev09_126254_persistent_aux_allocators/test.cpp +++ b/tests/std/tests/Dev09_126254_persistent_aux_allocators/test.cpp @@ -98,10 +98,12 @@ void dump_map() { } } +#pragma warning(push) +#pragma warning(disable : 4324) // structure was padded due to alignment specifier struct alignas(64) OverAlignedInt { int x; -#pragma warning(suppress : 4324) // structure was padded due to alignment specifier }; +#pragma warning(pop) void test_gh_2362() { // GH-2362 suggests to add a debug-only nullptr assertion inside std::allocator::deallocate, checking diff --git a/tests/std/tests/Dev09_158457_tr1_mem_fn_calling_conventions/test.cpp b/tests/std/tests/Dev09_158457_tr1_mem_fn_calling_conventions/test.cpp index 0187f23f355..fcfcc11bea1 100644 --- a/tests/std/tests/Dev09_158457_tr1_mem_fn_calling_conventions/test.cpp +++ b/tests/std/tests/Dev09_158457_tr1_mem_fn_calling_conventions/test.cpp @@ -200,7 +200,7 @@ STATIC_ASSERT(is_function_v); // non-viable.) template -int use_mem_fn(R Cat::*pmf) { +int use_mem_fn(R Cat::* pmf) { Cat cat; return mem_fn(pmf)(cat); } diff --git a/tests/std/tests/Dev09_173612_tr1_regex_leak/test.cpp b/tests/std/tests/Dev09_173612_tr1_regex_leak/test.cpp index f74e3eaefcf..1dfa529bc83 100644 --- a/tests/std/tests/Dev09_173612_tr1_regex_leak/test.cpp +++ b/tests/std/tests/Dev09_173612_tr1_regex_leak/test.cpp @@ -157,7 +157,9 @@ void test(const char* s) { const int orig_scalars = g_scalars; const int orig_arrays = g_arrays; - { regex r(s); } + { + regex r(s); + } if (g_scalars != orig_scalars) { printf("test(): %d scalar allocation leak(s)!\n", g_scalars - orig_scalars); diff --git a/tests/std/tests/Dev10_491486_floating_point_hash/test.cpp b/tests/std/tests/Dev10_491486_floating_point_hash/test.cpp index 8d18750ea3f..91fb0f1d9c1 100644 --- a/tests/std/tests/Dev10_491486_floating_point_hash/test.cpp +++ b/tests/std/tests/Dev10_491486_floating_point_hash/test.cpp @@ -29,8 +29,10 @@ void test_case() { assert(fake_bit_cast(pos0d) == 0); const auto neg0d = static_cast(0.0 * -1.0); assert(fake_bit_cast(neg0d) == topBitSet); -#pragma warning(suppress : 6326) // potential comparison of a constant with another constant +#pragma warning(push) +#pragma warning(disable : 6326) // potential comparison of a constant with another constant assert(pos0d == neg0d); +#pragma warning(pop) assert(hash()(pos0d) == hash()(neg0d)); array a{{ diff --git a/tests/std/tests/Dev10_561430_list_and_tree_leaks/test.cpp b/tests/std/tests/Dev10_561430_list_and_tree_leaks/test.cpp index 159da7d9d99..99952f17f12 100644 --- a/tests/std/tests/Dev10_561430_list_and_tree_leaks/test.cpp +++ b/tests/std/tests/Dev10_561430_list_and_tree_leaks/test.cpp @@ -116,9 +116,13 @@ int main() { } #endif // _HAS_FUNCTION_ALLOCATOR_SUPPORT - { shared_ptr sp(new int(1729), default_delete(), Mallocator()); } + { + shared_ptr sp(new int(1729), default_delete(), Mallocator()); + } - { shared_ptr sp = allocate_shared(Mallocator(), 1729); } + { + shared_ptr sp = allocate_shared(Mallocator(), 1729); + } #ifndef _M_CEE_PURE { diff --git a/tests/std/tests/Dev10_814245_regex_character_class_crash/test.cpp b/tests/std/tests/Dev10_814245_regex_character_class_crash/test.cpp index ab6f047f9b6..26a8f89605d 100644 --- a/tests/std/tests/Dev10_814245_regex_character_class_crash/test.cpp +++ b/tests/std/tests/Dev10_814245_regex_character_class_crash/test.cpp @@ -111,12 +111,39 @@ void test_VSO_984741_splitting_a_string_with_a_regex() { assert(equal(i, sregex_token_iterator{}, begin(tokens), end(tokens))); } +void test_gh_5164_case_insensitive_ranges() { + using ch_traits = char_traits; + const regex_traits re_traits; + for (size_t upper = 0; upper < characterCount; ++upper) { + for (size_t lower = 0; lower < characterCount; ++lower) { + const string pattern(g_firstCharacters[lower] + "-" + g_secondCharacters[upper]); + const char left_bound = re_traits.translate_nocase(g_inputs[lower][0]); + const char right_bound = re_traits.translate_nocase(g_inputs[upper][0]); + + if (ch_traits::lt(right_bound, left_bound)) { + g_regexTester.should_throw(pattern, error_range, icase); + } else { + const regex r(pattern, icase); + for (size_t c = 0; c < characterCount; ++c) { + const char input_icase = re_traits.translate_nocase(g_inputs[c][0]); + if (ch_traits::lt(input_icase, left_bound) || ch_traits::lt(right_bound, input_icase)) { + g_regexTester.should_not_match(g_inputs[c], pattern, r); + } else { + g_regexTester.should_match(g_inputs[c], pattern, r); + } + } + } + } + } +} + int main() { init_character_strings(); test_dev10_814245_character_class_should_not_crash(); test_dev10_723057_normal_to_high_bit_ranges_should_not_throw_error_range(); test_VSO_153556_singular_classes_can_have_high_bit_set(); test_VSO_984741_splitting_a_string_with_a_regex(); + test_gh_5164_case_insensitive_ranges(); return g_regexTester.result(); } diff --git a/tests/std/tests/Dev11_0535636_functional_overhaul/test.cpp b/tests/std/tests/Dev11_0535636_functional_overhaul/test.cpp index 492030269dc..cc2fabe66af 100644 --- a/tests/std/tests/Dev11_0535636_functional_overhaul/test.cpp +++ b/tests/std/tests/Dev11_0535636_functional_overhaul/test.cpp @@ -1017,7 +1017,7 @@ void test_reference_wrapper_invocation() { pmf = &Thing::product; assert(rw_pmf(sp, 3) == 60000); - int Thing::*pmd = &Thing::m_x; + int Thing::* pmd = &Thing::m_x; reference_wrapper rw_pmd(pmd); assert(rw_pmd(*sp) == 1000); assert(rw_pmd(sp.get()) == 1000); diff --git a/tests/std/tests/Dev11_0617384_empty_std_function/test.cpp b/tests/std/tests/Dev11_0617384_empty_std_function/test.cpp index 16ae8abdb4b..1b528030f81 100644 --- a/tests/std/tests/Dev11_0617384_empty_std_function/test.cpp +++ b/tests/std/tests/Dev11_0617384_empty_std_function/test.cpp @@ -35,7 +35,7 @@ int main() { #endif // _HAS_FUNCTION_ALLOCATOR_SUPPORT int (X::*pmf)(int) = nullptr; - int X::*pmd = nullptr; + int X::* pmd = nullptr; assert(!function(pmf)); assert(!function(pmd)); diff --git a/tests/std/tests/Dev11_0836436_get_time/test.cpp b/tests/std/tests/Dev11_0836436_get_time/test.cpp index 6c05df8bd3f..ff7a8be5b97 100644 --- a/tests/std/tests/Dev11_0836436_get_time/test.cpp +++ b/tests/std/tests/Dev11_0836436_get_time/test.cpp @@ -912,7 +912,7 @@ void test_gh_4820() { void test_gh_4882() { // GH-4882 : std::put_time should not crash on invalid/out-of-range tm struct values - const auto fieldValidation = [](int tm::*const field, const int value, const string& fmt) { + const auto fieldValidation = [](int tm::* const field, const int value, const string& fmt) { time_t t = time(nullptr); tm currentTime; localtime_s(¤tTime, &t); @@ -939,7 +939,7 @@ void test_gh_4882() { }; struct FormatTestData { - int tm::*field; + int tm::* field; int lo; int hi; string fmt; diff --git a/tests/std/tests/GH_000431_copy_move_family/test.cpp b/tests/std/tests/GH_000431_copy_move_family/test.cpp index 125792ea6e4..3527ebf0bb7 100644 --- a/tests/std/tests/GH_000431_copy_move_family/test.cpp +++ b/tests/std/tests/GH_000431_copy_move_family/test.cpp @@ -37,7 +37,8 @@ struct TrivialStruct { return i == right.i; } }; -STATIC_ASSERT(is_trivial_v); +STATIC_ASSERT(is_trivially_copyable_v); +STATIC_ASSERT(is_trivially_default_constructible_v); struct TriviallyCopyableStruct { int i; @@ -49,7 +50,7 @@ struct TriviallyCopyableStruct { } }; STATIC_ASSERT(is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyMovableStruct { int i; @@ -65,7 +66,7 @@ struct TriviallyMovableStruct { } }; STATIC_ASSERT(is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); enum int_enum : int {}; enum char_enum : char {}; diff --git a/tests/std/tests/GH_000431_iter_copy_move_cat/test.compile.pass.cpp b/tests/std/tests/GH_000431_iter_copy_move_cat/test.compile.pass.cpp index cac035a3e90..8041ee4127e 100644 --- a/tests/std/tests/GH_000431_iter_copy_move_cat/test.compile.pass.cpp +++ b/tests/std/tests/GH_000431_iter_copy_move_cat/test.compile.pass.cpp @@ -170,14 +170,15 @@ void test_iter_cat_for_containers() { struct TrivialStruct { int i; }; -STATIC_ASSERT(is_trivial_v); +STATIC_ASSERT(is_trivially_copyable_v); +STATIC_ASSERT(is_trivially_default_constructible_v); struct TriviallyCopyableStruct { int i; TriviallyCopyableStruct(); }; STATIC_ASSERT(is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyMovableStruct { int i; @@ -188,7 +189,7 @@ struct TriviallyMovableStruct { TriviallyMovableStruct& operator=(TriviallyMovableStruct&&) = default; }; STATIC_ASSERT(is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyConstructibleStruct { int i; @@ -204,7 +205,7 @@ STATIC_ASSERT(is_trivially_move_constructible_v); STATIC_ASSERT(!is_trivially_copy_assignable_v); STATIC_ASSERT(!is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyAssignableStruct { int i; @@ -220,7 +221,7 @@ STATIC_ASSERT(!is_trivially_move_constructible_v); STATIC_ASSERT(is_trivially_copy_assignable_v); STATIC_ASSERT(is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyCopyConstructibleStruct { int i; @@ -236,7 +237,7 @@ STATIC_ASSERT(!is_trivially_move_constructible_v); STATIC_ASSERT(!is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyCopyAssignableStruct { int i; @@ -253,7 +254,7 @@ STATIC_ASSERT(!is_trivially_move_constructible_v) STATIC_ASSERT(is_trivially_copy_assignable_v); STATIC_ASSERT(!is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyMoveConstructibleStruct { int i; @@ -269,7 +270,7 @@ STATIC_ASSERT(is_trivially_move_constructible_v); STATIC_ASSERT(!is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyMoveAssignableStruct { int i; @@ -285,7 +286,7 @@ STATIC_ASSERT(!is_trivially_move_constructible_v) STATIC_ASSERT(!is_trivially_copy_assignable_v); STATIC_ASSERT(is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct EmptyBase {}; diff --git a/tests/std/tests/GH_001858_iostream_exception/test.cpp b/tests/std/tests/GH_001858_iostream_exception/test.cpp index 7c23e0ff118..eaec61efee0 100644 --- a/tests/std/tests/GH_001858_iostream_exception/test.cpp +++ b/tests/std/tests/GH_001858_iostream_exception/test.cpp @@ -619,15 +619,15 @@ STATIC_ASSERT( STATIC_ASSERT( !is_nothrow_move_assignable_v, pmr::polymorphic_allocator>>); STATIC_ASSERT(!is_nothrow_move_assignable_v< - basic_istringstream, pmr::polymorphic_allocator>>); + basic_istringstream, pmr::polymorphic_allocator>>); STATIC_ASSERT( !is_nothrow_move_assignable_v, pmr::polymorphic_allocator>>); STATIC_ASSERT(!is_nothrow_move_assignable_v< - basic_ostringstream, pmr::polymorphic_allocator>>); + basic_ostringstream, pmr::polymorphic_allocator>>); STATIC_ASSERT( !is_nothrow_move_assignable_v, pmr::polymorphic_allocator>>); STATIC_ASSERT(!is_nothrow_move_assignable_v< - basic_stringstream, pmr::polymorphic_allocator>>); + basic_stringstream, pmr::polymorphic_allocator>>); #endif // _HAS_CXX17 STATIC_ASSERT(is_nothrow_std_swappable); diff --git a/tests/std/tests/GH_002030_asan_annotate_string/env.lst b/tests/std/tests/GH_002030_asan_annotate_string/env.lst index 08acc3dc792..9ea027b4346 100644 --- a/tests/std/tests/GH_002030_asan_annotate_string/env.lst +++ b/tests/std/tests/GH_002030_asan_annotate_string/env.lst @@ -9,32 +9,50 @@ RUNALL_INCLUDE ..\prefix.lst RUNALL_CROSSLIST PM_CL="/Zi /wd4611 /w14640 /Zc:threadSafeInit-" PM_LINK="/debug" RUNALL_CROSSLIST -PM_CL="-fsanitize=address" -PM_CL="/D_ANNOTATE_STRING" -RUNALL_CROSSLIST -PM_CL="/BE /c /EHsc /MD /std:c++14" -PM_CL="/BE /c /EHsc /MDd /std:c++17 /permissive-" -PM_CL="/BE /c /EHsc /MT /std:c++20 /permissive-" -PM_CL="/BE /c /EHsc /MTd /std:c++latest /permissive-" -PM_CL="/EHsc /MD /std:c++14" -PM_CL="/EHsc /MD /std:c++14 /Zc:char8_t" -PM_CL="/EHsc /MD /std:c++17" -PM_CL="/EHsc /MD /std:c++17 /Zc:char8_t" -PM_CL="/EHsc /MD /std:c++20" -PM_CL="/EHsc /MD /std:c++latest /permissive- /Zc:char8_t- /Zc:preprocessor" -PM_CL="/EHsc /MD /std:c++latest /permissive- /Zc:noexceptTypes-" -PM_CL="/EHsc /MDd /std:c++14 /fp:except /Zc:preprocessor" -PM_CL="/EHsc /MDd /std:c++17 /permissive-" -PM_CL="/EHsc /MDd /std:c++20 /permissive-" -PM_CL="/EHsc /MDd /std:c++latest /permissive- /Zc:wchar_t-" -PM_CL="/EHsc /MDd /std:c++latest /permissive-" -PM_CL="/EHsc /MT /std:c++latest /permissive- /analyze:only /analyze:autolog-" -PM_CL="/EHsc /MT /std:c++latest /permissive-" -PM_CL="/EHsc /MTd /std:c++latest /permissive" -PM_CL="/EHsc /MTd /std:c++latest /permissive- /analyze:only /analyze:autolog-" -PM_CL="/EHsc /MTd /std:c++latest /permissive- /fp:strict" -PM_CL="/EHsc /MTd /std:c++latest /permissive-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++14" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++17" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++20 /permissive-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++latest /permissive- /fp:strict" +PM_CL="-fsanitize=address /BE /c /EHsc /MD /std:c++14" +PM_CL="-fsanitize=address /BE /c /EHsc /MDd /std:c++17 /permissive-" +PM_CL="-fsanitize=address /BE /c /EHsc /MT /std:c++20 /permissive-" +PM_CL="-fsanitize=address /BE /c /EHsc /MTd /std:c++latest /permissive-" +PM_CL="-fsanitize=address /EHsc /MD /std:c++14" +PM_CL="-fsanitize=address /EHsc /MD /std:c++17" +PM_CL="-fsanitize=address /EHsc /MD /std:c++20" +PM_CL="-fsanitize=address /EHsc /MD /std:c++latest /permissive- /Zc:char8_t- /Zc:preprocessor" +PM_CL="-fsanitize=address /EHsc /MD /std:c++latest /permissive- /Zc:noexceptTypes-" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++14 /fp:except /Zc:preprocessor" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++17 /permissive-" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++20 /permissive-" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++latest /permissive- /Zc:wchar_t-" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++latest /permissive-" +PM_CL="-fsanitize=address /EHsc /MT /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="-fsanitize=address /EHsc /MT /std:c++latest /permissive-" +PM_CL="-fsanitize=address /EHsc /MTd /std:c++latest /permissive" +PM_CL="-fsanitize=address /EHsc /MTd /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="-fsanitize=address /EHsc /MTd /std:c++latest /permissive- /fp:strict" +PM_CL="-fsanitize=address /EHsc /MTd /std:c++latest /permissive-" +PM_CL="/D_ANNOTATE_STRING /BE /c /EHsc /MD /std:c++14" +PM_CL="/D_ANNOTATE_STRING /BE /c /EHsc /MDd /std:c++17 /permissive-" +PM_CL="/D_ANNOTATE_STRING /BE /c /EHsc /MT /std:c++20 /permissive-" +PM_CL="/D_ANNOTATE_STRING /BE /c /EHsc /MTd /std:c++latest /permissive-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MD /std:c++14" +PM_CL="/D_ANNOTATE_STRING /EHsc /MD /std:c++14 /Zc:char8_t" +PM_CL="/D_ANNOTATE_STRING /EHsc /MD /std:c++17" +PM_CL="/D_ANNOTATE_STRING /EHsc /MD /std:c++17 /Zc:char8_t" +PM_CL="/D_ANNOTATE_STRING /EHsc /MD /std:c++20" +PM_CL="/D_ANNOTATE_STRING /EHsc /MD /std:c++latest /permissive- /Zc:char8_t- /Zc:preprocessor" +PM_CL="/D_ANNOTATE_STRING /EHsc /MD /std:c++latest /permissive- /Zc:noexceptTypes-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MDd /std:c++14 /fp:except /Zc:preprocessor" +PM_CL="/D_ANNOTATE_STRING /EHsc /MDd /std:c++17 /permissive-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MDd /std:c++20 /permissive-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MDd /std:c++latest /permissive- /Zc:wchar_t-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MDd /std:c++latest /permissive-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MT /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MT /std:c++latest /permissive-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MTd /std:c++latest /permissive" +PM_CL="/D_ANNOTATE_STRING /EHsc /MTd /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MTd /std:c++latest /permissive- /fp:strict" +PM_CL="/D_ANNOTATE_STRING /EHsc /MTd /std:c++latest /permissive-" +# TRANSITION, we don't use /ALTERNATENAME for Clang (see GH-5224) so we cannot test /D_ANNOTATE_STRING without -fsanitize=address +PM_COMPILER="clang-cl" PM_CL="-fsanitize=address -fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++14" +PM_COMPILER="clang-cl" PM_CL="-fsanitize=address -fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++17" +PM_COMPILER="clang-cl" PM_CL="-fsanitize=address -fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++20 /permissive-" +PM_COMPILER="clang-cl" PM_CL="-fsanitize=address -fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++latest /permissive- /fp:strict" diff --git a/tests/std/tests/GH_002030_asan_annotate_vector/env.lst b/tests/std/tests/GH_002030_asan_annotate_vector/env.lst index 4182c344a2e..e644474d29a 100644 --- a/tests/std/tests/GH_002030_asan_annotate_vector/env.lst +++ b/tests/std/tests/GH_002030_asan_annotate_vector/env.lst @@ -8,30 +8,48 @@ RUNALL_INCLUDE ..\prefix.lst RUNALL_CROSSLIST PM_CL="/Zi /wd4611 /w14640 /Zc:threadSafeInit-" PM_LINK="/debug" RUNALL_CROSSLIST -PM_CL="-fsanitize=address" -PM_CL="/D_ANNOTATE_VECTOR" -RUNALL_CROSSLIST -PM_CL="/BE /c /EHsc /MD /std:c++14" -PM_CL="/BE /c /EHsc /MDd /std:c++17 /permissive-" -PM_CL="/BE /c /EHsc /MT /std:c++20 /permissive-" -PM_CL="/BE /c /EHsc /MTd /std:c++latest /permissive-" -PM_CL="/EHsc /MD /std:c++14" -PM_CL="/EHsc /MD /std:c++17" -PM_CL="/EHsc /MD /std:c++20" -PM_CL="/EHsc /MD /std:c++latest /permissive- /Zc:char8_t- /Zc:preprocessor" -PM_CL="/EHsc /MD /std:c++latest /permissive- /Zc:noexceptTypes-" -PM_CL="/EHsc /MDd /std:c++14 /fp:except /Zc:preprocessor" -PM_CL="/EHsc /MDd /std:c++17 /permissive-" -PM_CL="/EHsc /MDd /std:c++20 /permissive-" -PM_CL="/EHsc /MDd /std:c++latest /permissive- /Zc:wchar_t-" -PM_CL="/EHsc /MDd /std:c++latest /permissive-" -PM_CL="/EHsc /MT /std:c++latest /permissive- /analyze:only /analyze:autolog-" -PM_CL="/EHsc /MT /std:c++latest /permissive-" -PM_CL="/EHsc /MTd /std:c++latest /permissive" -PM_CL="/EHsc /MTd /std:c++latest /permissive- /analyze:only /analyze:autolog-" -PM_CL="/EHsc /MTd /std:c++latest /permissive- /fp:strict" -PM_CL="/EHsc /MTd /std:c++latest /permissive-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++14" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++17" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++20 /permissive-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++latest /permissive- /fp:strict" +PM_CL="-fsanitize=address /BE /c /EHsc /MD /std:c++14" +PM_CL="-fsanitize=address /BE /c /EHsc /MDd /std:c++17 /permissive-" +PM_CL="-fsanitize=address /BE /c /EHsc /MT /std:c++20 /permissive-" +PM_CL="-fsanitize=address /BE /c /EHsc /MTd /std:c++latest /permissive-" +PM_CL="-fsanitize=address /EHsc /MD /std:c++14" +PM_CL="-fsanitize=address /EHsc /MD /std:c++17" +PM_CL="-fsanitize=address /EHsc /MD /std:c++20" +PM_CL="-fsanitize=address /EHsc /MD /std:c++latest /permissive- /Zc:char8_t- /Zc:preprocessor" +PM_CL="-fsanitize=address /EHsc /MD /std:c++latest /permissive- /Zc:noexceptTypes-" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++14 /fp:except /Zc:preprocessor" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++17 /permissive-" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++20 /permissive-" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++latest /permissive- /Zc:wchar_t-" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++latest /permissive-" +PM_CL="-fsanitize=address /EHsc /MT /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="-fsanitize=address /EHsc /MT /std:c++latest /permissive-" +PM_CL="-fsanitize=address /EHsc /MTd /std:c++latest /permissive" +PM_CL="-fsanitize=address /EHsc /MTd /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="-fsanitize=address /EHsc /MTd /std:c++latest /permissive- /fp:strict" +PM_CL="-fsanitize=address /EHsc /MTd /std:c++latest /permissive-" +PM_CL="/D_ANNOTATE_VECTOR /BE /c /EHsc /MD /std:c++14" +PM_CL="/D_ANNOTATE_VECTOR /BE /c /EHsc /MDd /std:c++17 /permissive-" +PM_CL="/D_ANNOTATE_VECTOR /BE /c /EHsc /MT /std:c++20 /permissive-" +PM_CL="/D_ANNOTATE_VECTOR /BE /c /EHsc /MTd /std:c++latest /permissive-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MD /std:c++14" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MD /std:c++17" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MD /std:c++20" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MD /std:c++latest /permissive- /Zc:char8_t- /Zc:preprocessor" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MD /std:c++latest /permissive- /Zc:noexceptTypes-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MDd /std:c++14 /fp:except /Zc:preprocessor" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MDd /std:c++17 /permissive-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MDd /std:c++20 /permissive-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MDd /std:c++latest /permissive- /Zc:wchar_t-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MDd /std:c++latest /permissive-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MT /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MT /std:c++latest /permissive-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MTd /std:c++latest /permissive" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MTd /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MTd /std:c++latest /permissive- /fp:strict" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MTd /std:c++latest /permissive-" +# TRANSITION, we don't use /ALTERNATENAME for Clang (see GH-5224) so we cannot test /D_ANNOTATE_VECTOR without -fsanitize=address +PM_COMPILER="clang-cl" PM_CL="-fsanitize=address -fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++14" +PM_COMPILER="clang-cl" PM_CL="-fsanitize=address -fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++17" +PM_COMPILER="clang-cl" PM_CL="-fsanitize=address -fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++20 /permissive-" +PM_COMPILER="clang-cl" PM_CL="-fsanitize=address -fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++latest /permissive- /fp:strict" diff --git a/tests/std/tests/GH_002206_unreserved_names/test.compile.pass.cpp b/tests/std/tests/GH_002206_unreserved_names/test.compile.pass.cpp index 8ba419dbd06..302200fc3ef 100644 --- a/tests/std/tests/GH_002206_unreserved_names/test.compile.pass.cpp +++ b/tests/std/tests/GH_002206_unreserved_names/test.compile.pass.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #define ISA_AVAILABILITY delete +#define error_parse delete #define nsec delete #define sec delete #define xtime delete diff --git a/tests/std/tests/GH_002581_common_reference_workaround/test.compile.pass.cpp b/tests/std/tests/GH_002581_common_reference_workaround/test.compile.pass.cpp index 4dff687801e..4fbb07e70f9 100644 --- a/tests/std/tests/GH_002581_common_reference_workaround/test.compile.pass.cpp +++ b/tests/std/tests/GH_002581_common_reference_workaround/test.compile.pass.cpp @@ -23,8 +23,8 @@ static_assert(contiguous_iterator); static_assert(contiguous_iterator); static_assert(contiguous_iterator); static_assert(contiguous_iterator); -static_assert(contiguous_iterator); -static_assert(contiguous_iterator); +static_assert(contiguous_iterator); +static_assert(contiguous_iterator); // Tests for move_iterator specializations static_assert(random_access_iterator>); @@ -39,5 +39,5 @@ static_assert(random_access_iterator>); static_assert(random_access_iterator>); static_assert(random_access_iterator>); static_assert(random_access_iterator>); -static_assert(random_access_iterator>); -static_assert(random_access_iterator>); +static_assert(random_access_iterator>); +static_assert(random_access_iterator>); diff --git a/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp index c48709d1875..b26ca701f86 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp @@ -19,9 +19,10 @@ constexpr void check_members(const extents& ext, index_se using Ext = extents; using Mapping = layout_left::mapping; - // layout_left meets the layout mapping policy requirements and is a trivial type + // layout_left meets the requirements of N5001 [mdspan.layout.policy.overview]/1 static_assert(check_layout_mapping_policy_requirements()); - static_assert(is_trivial_v); + static_assert(is_trivially_copyable_v); + static_assert(is_trivially_default_constructible_v); // layout_left::mapping is a trivially copyable type that models regular for each Ext static_assert(is_trivially_copyable_v); @@ -203,7 +204,7 @@ constexpr void check_construction_from_other_left_mapping() { { // Check implicit conversions static_assert(!NotImplicitlyConstructibleFrom>, - layout_left::mapping>>); + layout_left::mapping>>); static_assert(NotImplicitlyConstructibleFrom>, layout_left::mapping>>); static_assert(NotImplicitlyConstructibleFrom>, diff --git a/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp index ef08dd7e9a9..89899ab408c 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp @@ -19,9 +19,10 @@ constexpr void check_members(const extents& ext, index_se using Ext = extents; using Mapping = layout_right::mapping; - // layout_right meets the layout mapping policy requirements and is a trivial type + // layout_right meets the requirements of N5001 [mdspan.layout.policy.overview]/1 static_assert(check_layout_mapping_policy_requirements()); - static_assert(is_trivial_v); + static_assert(is_trivially_copyable_v); + static_assert(is_trivially_default_constructible_v); // layout_right::mapping is a trivially copyable type that models regular for each Ext static_assert(is_trivially_copyable_v); @@ -202,7 +203,7 @@ constexpr void check_construction_from_other_right_mapping() { { // Check implicit conversions static_assert(!NotImplicitlyConstructibleFrom>, - layout_right::mapping>>); + layout_right::mapping>>); static_assert(NotImplicitlyConstructibleFrom>, layout_right::mapping>>); static_assert(NotImplicitlyConstructibleFrom>, diff --git a/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp index 5f34b8c1541..f2dadd09de6 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp @@ -105,9 +105,10 @@ constexpr void do_check_members(const extents& ext, using Strides = array; using Mapping = layout_stride::mapping; - // layout_stride meets the layout mapping policy requirements and is a trivial type + // layout_stride meets the requirements of N5001 [mdspan.layout.policy.overview]/1 static_assert(check_layout_mapping_policy_requirements()); - static_assert(is_trivial_v); + static_assert(is_trivially_copyable_v); + static_assert(is_trivially_default_constructible_v); // layout_stride::mapping is a trivially copyable type that models regular for each Ext static_assert(is_trivially_copyable_v); @@ -352,11 +353,11 @@ constexpr void check_construction_from_other_mappings() { static_assert(!is_constructible_v>>); static_assert(!is_constructible_v>>); static_assert(!is_constructible_v::mapping>>); + LyingLayout::mapping>>); static_assert(!is_constructible_v::mapping>>); + LyingLayout::mapping>>); static_assert(!is_constructible_v::mapping>>); + LyingLayout::mapping>>); } { // Check construction from layout_left::mapping @@ -539,13 +540,13 @@ constexpr void check_comparisons() { static_assert(!equality_comparable_with>>); static_assert(!equality_comparable_with>>); static_assert(!equality_comparable_with::mapping>>); + LyingLayout::mapping>>); static_assert(!equality_comparable_with::mapping>>); + LyingLayout::mapping>>); static_assert(!equality_comparable_with::mapping>>); + LyingLayout::mapping>>); static_assert(!equality_comparable_with::mapping>>); + LyingLayout::mapping>>); } { // Check correctness: layout_stride::mapping with layout_stride::mapping diff --git a/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp b/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp index c68533ccd0e..330d3cadc34 100644 --- a/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp @@ -337,7 +337,8 @@ struct TrivialAccessor { }; static_assert(check_accessor_policy_requirements>()); -static_assert(is_trivial_v>); +static_assert(is_trivially_copyable_v>); +static_assert(is_trivially_default_constructible_v>); template class AccessorTemplate> constexpr void check_modeled_concepts_and_member_types() { @@ -601,9 +602,9 @@ constexpr void check_data_handle_and_span_array_constructors() { static_assert(is_nothrow_constructible_v, layout_right, VectorBoolAccessor>, vector::iterator, array>); // strengthened static_assert(!is_constructible_v, layout_right, TrackingAccessor>, int*, - span>); + span>); static_assert(!is_constructible_v, layout_right, TrackingAccessor>, int*, - array>); + array>); } { // Check explicitness @@ -688,9 +689,9 @@ constexpr void check_data_handle_and_extents_constructor() { static_assert(is_nothrow_constructible_v, layout_right, VectorBoolAccessor>, vector::iterator, extents>); // strengthened static_assert(!is_constructible_v, layout_right, TrackingAccessor>, int*, - dextents>); + dextents>); static_assert(!is_constructible_v, layout_right, TrackingAccessor>, int*, - extents>); + extents>); } { // Check effects: 'direct-non-list-initializes ptr_ with std::move(p)' @@ -721,11 +722,11 @@ constexpr void check_data_handle_and_mapping_constructor() { static_assert(is_nothrow_constructible_v, layout_left>, int* const, layout_left::mapping>>); // strengthened static_assert(!is_constructible_v< - mdspan, extents, TrackingLayout<>, TrackingAccessor>>, - vector*, TrackingLayout<>::mapping>>); + mdspan, extents, TrackingLayout<>, TrackingAccessor>>, vector*, + TrackingLayout<>::mapping>>); static_assert(!is_constructible_v< - mdspan, extents, TrackingLayout<>, TrackingAccessor>>, - deque* const, TrackingLayout<>::mapping>>); + mdspan, extents, TrackingLayout<>, TrackingAccessor>>, + deque* const, TrackingLayout<>::mapping>>); } { // Check effect: 'direct-non-list-initializes ptr_ with std::move(p)' @@ -780,7 +781,7 @@ constexpr void check_data_handle_and_mapping_and_accessor_constructor() { using Mds2 = mdspan, TrackingLayout<>>; static_assert(!is_nothrow_constructible_v); + const Mds2::accessor_type&>); } } @@ -790,9 +791,9 @@ constexpr void check_construction_from_other_mdspan() { static_assert(is_nothrow_constructible_v, layout_stride>, mdspan, layout_right>>); // strengthened static_assert(!is_constructible_v, layout_left>, - mdspan, layout_right>>); + mdspan, layout_right>>); static_assert(!is_constructible_v, layout_left>, - mdspan, layout_left>>); + mdspan, layout_left>>); } { // Check constraint: 'is_constructible_v' @@ -801,7 +802,7 @@ constexpr void check_construction_from_other_mdspan() { is_nothrow_constructible_v>, mdspan>>); // strengthened static_assert(!is_constructible_v>, - mdspan>>); + mdspan>>); } { // Check explicitness @@ -809,13 +810,13 @@ constexpr void check_construction_from_other_mdspan() { static_assert(NotImplicitlyConstructibleFrom, layout_left>, mdspan, layout_stride>>); static_assert(!NotImplicitlyConstructibleFrom, layout_stride>, - mdspan, layout_left>>); + mdspan, layout_left>>); static_assert(NotImplicitlyConstructibleFrom< mdspan, layout_left, AccessorWithCustomOffsetPolicy>, mdspan, layout_left, AccessorWithCustomOffsetPolicy>>); static_assert(!NotImplicitlyConstructibleFrom< - mdspan, layout_left, default_accessor>, - mdspan, layout_left, default_accessor>>); + mdspan, layout_left, default_accessor>, + mdspan, layout_left, default_accessor>>); } { // Check effects diff --git a/tests/std/tests/P0019R8_atomic_ref/test.cpp b/tests/std/tests/P0019R8_atomic_ref/test.cpp index 8edf08cfd9e..47f42a78be0 100644 --- a/tests/std/tests/P0019R8_atomic_ref/test.cpp +++ b/tests/std/tests/P0019R8_atomic_ref/test.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -34,50 +35,256 @@ struct int128 { } }; -// Also test GH-4688 ": atomic_ref and atomic lack difference_type" +// Also test constraints and conditional existence of difference_type specified by +// P3323R1 "Forbid atomic, Specify atomic_ref". + +template +void test_atomic_ref_constraints_single() { // COMPILE-ONLY + using TD = std::remove_cv_t; + using AR = std::atomic_ref; + + static_assert(std::is_same_v); + static_assert(requires(const AR& r, TD v, std::memory_order ord) { + r.operator TD(); + { r.load() } -> std::same_as; + { r.load(ord) } -> std::same_as; + { r.wait(v) } -> std::same_as; + { r.wait(v, ord) } -> std::same_as; + }); + { + [[maybe_unused]] auto instantiator = [](const AR& r, TD v, std::memory_order ord) { +#if defined(__clang__) || defined(__EDG__) // TRANSITION, VSO-2343282 + (void) r.operator TD(); +#else // ^^^ no workaround / workaround vvv + [[maybe_unused]] TD td = r; +#endif // ^^^ workaround ^^^ + (void) r.load(); + (void) r.load(ord); + r.wait(v); + r.wait(v, ord); + }; + } + + if constexpr (!std::is_const_v) { + static_assert(requires(const AR& r, TD v, TD& vx, std::memory_order ord1, std::memory_order ord2) { + { r.store(v) } -> std::same_as; + { r.store(v, ord1) } -> std::same_as; + { r = v } -> std::same_as; + { r.exchange(v) } -> std::same_as; + { r.exchange(v, ord1) } -> std::same_as; + { r.compare_exchange_weak(vx, v) } -> std::same_as; + { r.compare_exchange_weak(vx, v, ord1) } -> std::same_as; + { r.compare_exchange_weak(vx, v, ord1, ord2) } -> std::same_as; + { r.compare_exchange_strong(vx, v) } -> std::same_as; + { r.compare_exchange_strong(vx, v, ord1) } -> std::same_as; + { r.compare_exchange_strong(vx, v, ord1, ord2) } -> std::same_as; + { r.notify_one() } -> std::same_as; + { r.notify_all() } -> std::same_as; + }); + + [[maybe_unused]] auto instantiator = [](const AR& r, TD v, TD& vx, std::memory_order ord1, + std::memory_order ord2) { + r.store(v); + r.store(v, ord1); + (void) (r = v); + (void) r.exchange(v); + (void) r.exchange(v, ord1); + (void) r.compare_exchange_weak(vx, v); + (void) r.compare_exchange_weak(vx, v, ord1); + (void) r.compare_exchange_weak(vx, v, ord1, ord2); + (void) r.compare_exchange_strong(vx, v); + (void) r.compare_exchange_strong(vx, v, ord1); + (void) r.compare_exchange_strong(vx, v, ord1, ord2); + r.notify_one(); + r.notify_all(); + }; + } else { + static_assert(!requires(const AR& r, TD v) { r.store(v); }); + static_assert(!requires(const AR& r, TD v, std::memory_order ord) { r.store(v, ord); }); + static_assert(!requires(const AR& r, TD v) { r = v; }); + static_assert(!requires(const AR& r, TD v) { r.exchange(v); }); + static_assert(!requires(const AR& r, TD v, std::memory_order ord) { r.exchange(v, ord); }); + static_assert(!requires(const AR& r, TD& v1, TD v2) { r.compare_exchange_weak(v1, v2); }); + static_assert( + !requires(const AR& r, TD& v1, TD v2, std::memory_order ord) { r.compare_exchange_weak(v1, v2, ord); }); + static_assert(!requires(const AR& r, TD& v1, TD v2, std::memory_order ord1, std::memory_order ord2) { + r.compare_exchange_weak(v1, v2, ord1, ord2); + }); + static_assert(!requires(const AR& r, TD& v1, TD v2) { r.compare_exchange_strong(v1, v2); }); + static_assert( + !requires(const AR& r, TD& v1, TD v2, std::memory_order ord) { r.compare_exchange_strong(v1, v2, ord); }); + static_assert(!requires(const AR& r, TD& v1, TD v2, std::memory_order ord1, std::memory_order ord2) { + r.compare_exchange_strong(v1, v2, ord1, ord2); + }); + static_assert(!requires(const AR& r) { r.notify_one(); }); + static_assert(!requires(const AR& r) { r.notify_all(); }); + } + + constexpr bool has_difference_type = (std::is_arithmetic_v && !std::is_same_v) + || (std::is_pointer_v && std::is_object_v>); + + if constexpr (has_difference_type) { + if constexpr (std::is_arithmetic_v) { + static_assert(std::is_same_v); + } else { + static_assert(std::is_same_v); + } + } else { + static_assert(!requires { typename AR::difference_type; }); + } + + if constexpr (has_difference_type && !std::is_const_v) { + static_assert(requires(const AR& r, AR::difference_type d, std::memory_order ord) { + { r.fetch_add(d) } -> std::same_as; + { r.fetch_add(d, ord) } -> std::same_as; + { r.fetch_sub(d) } -> std::same_as; + { r.fetch_sub(d, ord) } -> std::same_as; + { r += d } -> std::same_as; + { r -= d } -> std::same_as; + }); + + [[maybe_unused]] auto instantiator = [](const AR& r, AR::difference_type d, std::memory_order ord) { + (void) r.fetch_add(d); + (void) r.fetch_add(d, ord); + (void) r.fetch_sub(d); + (void) r.fetch_sub(d, ord); + (void) (r += d); + (void) (r -= d); + }; + } else { + static_assert(!requires(const AR& r, AR::difference_type d) { r.fetch_add(d); }); + static_assert(!requires(const AR& r, AR::difference_type d, std::memory_order ord) { r.fetch_add(d, ord); }); + static_assert(!requires(const AR& r, AR::difference_type d) { r.fetch_sub(d); }); + static_assert(!requires(const AR& r, AR::difference_type d, std::memory_order ord) { r.fetch_sub(d, ord); }); + static_assert(!requires(const AR& r, AR::difference_type d) { r += d; }); + static_assert(!requires(const AR& r, AR::difference_type d) { r -= d; }); + } + + if constexpr (has_difference_type && !std::is_floating_point_v && !std::is_const_v) { + static_assert(requires(const AR& r) { + { ++r } -> std::same_as; + { r++ } -> std::same_as; + { --r } -> std::same_as; + { r-- } -> std::same_as; + }); + + [[maybe_unused]] auto instantiator = [](const AR& r) { + (void) ++r; + (void) r++; + (void) --r; + (void) r--; + }; + } else { + static_assert(!requires(const AR& r) { ++r; }); + static_assert(!requires(const AR& r) { r++; }); + static_assert(!requires(const AR& r) { --r; }); + static_assert(!requires(const AR& r) { r--; }); + } + + if constexpr (std::is_integral_v && !std::is_same_v && !std::is_const_v) { + static_assert(requires(const AR& r, TD v, std::memory_order ord) { + { r.fetch_and(v) } -> std::same_as; + { r.fetch_and(v, ord) } -> std::same_as; + { r.fetch_or(v) } -> std::same_as; + { r.fetch_or(v, ord) } -> std::same_as; + { r.fetch_xor(v) } -> std::same_as; + { r.fetch_xor(v, ord) } -> std::same_as; + { r &= v } -> std::same_as; + { r |= v } -> std::same_as; + { r ^= v } -> std::same_as; + }); + + [[maybe_unused]] auto instantiator = [](const AR& r, TD v, std::memory_order ord) { + (void) r.fetch_and(v); + (void) r.fetch_and(v, ord); + (void) r.fetch_or(v); + (void) r.fetch_or(v, ord); + (void) r.fetch_xor(v); + (void) r.fetch_xor(v, ord); + (void) (r &= v); + (void) (r |= v); + (void) (r ^= v); + }; + } else { + static_assert(!requires(const AR& r, TD v) { r.fetch_and(v); }); + static_assert(!requires(const AR& r, TD v, std::memory_order ord) { r.fetch_and(v, ord); }); + static_assert(!requires(const AR& r, TD v) { r.fetch_or(v); }); + static_assert(!requires(const AR& r, TD v, std::memory_order ord) { r.fetch_or(v, ord); }); + static_assert(!requires(const AR& r, TD v) { r.fetch_xor(v); }); + static_assert(!requires(const AR& r, TD v, std::memory_order ord) { r.fetch_xor(v, ord); }); + static_assert(!requires(const AR& r, TD v) { r &= v; }); + static_assert(!requires(const AR& r, TD v) { r |= v; }); + static_assert(!requires(const AR& r, TD v) { r ^= v; }); + } +} + template -constexpr bool atomic_ref_has_member_difference_type = requires { typename std::atomic_ref::difference_type; }; - -static_assert(std::is_same_v::difference_type, signed char>); -static_assert(std::is_same_v::difference_type, short>); -static_assert(std::is_same_v::difference_type, int>); -static_assert(std::is_same_v::difference_type, long>); -static_assert(std::is_same_v::difference_type, long long>); -static_assert(std::is_same_v::difference_type, unsigned char>); -static_assert(std::is_same_v::difference_type, unsigned short>); -static_assert(std::is_same_v::difference_type, unsigned int>); -static_assert(std::is_same_v::difference_type, unsigned long>); -static_assert(std::is_same_v::difference_type, unsigned long long>); -static_assert(std::is_same_v::difference_type, char>); +void test_atomic_ref_constraints_cv() { // COMPILE-ONLY + static_assert(!std::is_const_v && !std::is_volatile_v); + test_atomic_ref_constraints_single(); + test_atomic_ref_constraints_single(); + if constexpr (std::atomic_ref::is_always_lock_free) { + test_atomic_ref_constraints_single(); + test_atomic_ref_constraints_single(); + } +} + +void test_atomic_ref_constraints() { // COMPILE-ONLY + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); #ifdef __cpp_char8_t -static_assert(std::is_same_v::difference_type, char8_t>); + test_atomic_ref_constraints_cv(); #endif // defined(__cpp_char8_t) -static_assert(std::is_same_v::difference_type, char16_t>); -static_assert(std::is_same_v::difference_type, char32_t>); -static_assert(std::is_same_v::difference_type, wchar_t>); - -static_assert(std::is_same_v::difference_type, float>); -static_assert(std::is_same_v::difference_type, double>); -static_assert(std::is_same_v::difference_type, long double>); - -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); - -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); - -static_assert(!atomic_ref_has_member_difference_type); -static_assert(!atomic_ref_has_member_difference_type); -static_assert(!atomic_ref_has_member_difference_type); -static_assert(!atomic_ref_has_member_difference_type); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + + test_atomic_ref_constraints_cv(); + + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); +} // code reuse of ../P1135R6_atomic_flag_test/test.cpp diff --git a/tests/std/tests/P0053R7_cpp_synchronized_buffered_ostream/test.cpp b/tests/std/tests/P0053R7_cpp_synchronized_buffered_ostream/test.cpp index a8f06f3af5a..c44d96a4ac9 100644 --- a/tests/std/tests/P0053R7_cpp_synchronized_buffered_ostream/test.cpp +++ b/tests/std/tests/P0053R7_cpp_synchronized_buffered_ostream/test.cpp @@ -348,7 +348,9 @@ void test_osyncstream(string_buffer* buf = nullptr) { // test synchronization OSyncStream oss(buf); oss << "Last "; - { OSyncStream(oss.get_wrapped()) << "First Input!\n"; } + { + OSyncStream(oss.get_wrapped()) << "First Input!\n"; + } oss << "Input!" << '\n'; } if (buf) { diff --git a/tests/std/tests/P0083R3_splicing_maps_and_sets/test.cpp b/tests/std/tests/P0083R3_splicing_maps_and_sets/test.cpp index 5d1c50b6056..c9bdbdd62f5 100644 --- a/tests/std/tests/P0083R3_splicing_maps_and_sets/test.cpp +++ b/tests/std/tests/P0083R3_splicing_maps_and_sets/test.cpp @@ -155,8 +155,12 @@ void test_node_handle(NodeHandle& nh1, NodeHandle& nh2, Validator1 v1, Validator CHECK_EMPTY(NodeHandle{}); #ifndef _M_CEE // TRANSITION, VSO-1664382 #if _HAS_CXX20 -#pragma warning(suppress : 4640) // C4640 emitted by MSVC because 'NodeHandle' type has non-trivial dtor - { static constinit NodeHandle static_handle{}; } +#pragma warning(push) +#pragma warning(disable : 4640) // C4640 emitted by MSVC because 'NodeHandle' type has non-trivial dtor + { + static constinit NodeHandle static_handle{}; + } +#pragma warning(pop) #endif // ^^^ _HAS_CXX20 ^^^ #endif // ^^^ no workaround ^^^ @@ -387,7 +391,7 @@ void test_merge_single() { } }(1); auto const pos = std::as_const(c1).find(key); - auto c2 = extended_merge_ctype{{0, 0}, {3, 3}}; + auto c2 = extended_merge_ctype{{0, 0}, {3, 3}}; allocation_allowed = false; assert(c1.get_allocator() == c2.get_allocator()); if constexpr (Move == should_move::yes) { diff --git a/tests/std/tests/P0218R1_filesystem/test.cpp b/tests/std/tests/P0218R1_filesystem/test.cpp index ef3e44f79c2..32413cd8215 100644 --- a/tests/std/tests/P0218R1_filesystem/test.cpp +++ b/tests/std/tests/P0218R1_filesystem/test.cpp @@ -1267,7 +1267,9 @@ void test_directory_iterator_common_parts(const string_view typeName) { // DirectoryIterator() noexcept; // ~DirectoryIterator(); - { DirectoryIterator default_ctor; } + { + DirectoryIterator default_ctor; + } // explicit DirectoryIterator(const path& _Path_arg); // DirectoryIterator(const path& _Path_arg, directory_options _Options_arg); diff --git a/tests/std/tests/P0220R1_optional/test.cpp b/tests/std/tests/P0220R1_optional/test.cpp index 34ed93ae66e..af8fe440199 100644 --- a/tests/std/tests/P0220R1_optional/test.cpp +++ b/tests/std/tests/P0220R1_optional/test.cpp @@ -8372,6 +8372,11 @@ int run_test() #include #include +#if _HAS_CXX20 +#define CONSTEXPR20 constexpr +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv +#define CONSTEXPR20 inline +#endif // ^^^ !_HAS_CXX20 ^^^ namespace msvc { namespace size { @@ -8422,12 +8427,6 @@ namespace msvc { namespace lwg3836 { static_assert(std::is_convertible_v, std::optional>); static_assert(std::is_convertible_v&, std::optional>); - -#if _HAS_CXX20 -#define CONSTEXPR20 constexpr -#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv -#define CONSTEXPR20 inline -#endif // ^^^ !_HAS_CXX20 ^^^ CONSTEXPR20 bool run_test() { std::optional oi = 0; std::optional ob = oi; @@ -8436,13 +8435,151 @@ namespace msvc { return true; } -#undef CONSTEXPR20 - #if _HAS_CXX20 static_assert(run_test()); #endif // _HAS_CXX20 } // namespace lwg3836 + namespace lwg3886 { + enum class Qualification { + None, + Const, + Volatile, + ConstVolatile, + }; + + template + constexpr Qualification CvQualOf = + std::is_const_v> + ? (std::is_volatile_v> ? Qualification::ConstVolatile : Qualification::Const) + : (std::is_volatile_v> ? Qualification::Volatile : Qualification::None); + + struct QualDistinction { + QualDistinction() = default; + + constexpr QualDistinction(QualDistinction&&) noexcept : qual_{Qualification::None} {} + constexpr QualDistinction(const QualDistinction&) noexcept : qual_{Qualification::Const} {} + template >, QualDistinction>, int> = + 0> + constexpr QualDistinction(T&&) noexcept : qual_{CvQualOf} {} + + constexpr QualDistinction& operator=(QualDistinction&&) noexcept { + qual_ = Qualification::None; + return *this; + } + constexpr QualDistinction& operator=(const QualDistinction&) noexcept { + qual_ = Qualification::Const; + return *this; + } + template >, QualDistinction>, int> = + 0> + constexpr QualDistinction& operator=(T&&) noexcept { + qual_ = CvQualOf; + return *this; + } + template >, QualDistinction>, int> = + 0> + constexpr const QualDistinction& operator=(T&&) const noexcept { + qual_ = CvQualOf; + return *this; + } + template >, QualDistinction>, int> = + 0> + volatile QualDistinction& operator=(T&&) volatile noexcept { + qual_ = CvQualOf; + return *this; + } + template >, QualDistinction>, int> = + 0> + const volatile QualDistinction& operator=(T&&) const volatile noexcept { + qual_ = CvQualOf; + return *this; + } + + mutable Qualification qual_ = Qualification::None; + }; + + constexpr bool test_value_or() { + assert(std::optional{}.value_or({}).qual_ == Qualification::None); + assert(std::optional{}.value_or({}).qual_ == Qualification::None); + { + std::optional opt; + assert(opt.value_or({}).qual_ == Qualification::None); + } + { + std::optional opt; + assert(opt.value_or({}).qual_ == Qualification::None); + } + return true; + } + + CONSTEXPR20 bool test_assignment() { + assert((std::optional{} = {QualDistinction{}}).value().qual_ == Qualification::None); + assert((std::optional{} = {QualDistinction{}}).value().qual_ == Qualification::None); + { + std::optional opt{std::in_place}; + assert((opt = {QualDistinction{}}).value().qual_ == Qualification::None); + opt.reset(); + assert((opt = {QualDistinction{}}).value().qual_ == Qualification::None); + } + { + std::optional opt{std::in_place}; + assert((opt = {QualDistinction{}}).value().qual_ == Qualification::None); + opt.reset(); + assert((opt = {QualDistinction{}}).value().qual_ == Qualification::None); + } + return true; + } + + bool test_volatile() { + assert(std::optional{}.value_or({}).qual_ == Qualification::None); + assert(std::optional{}.value_or({}).qual_ == Qualification::None); + { + std::optional opt; + assert(opt.value_or({}).qual_ == Qualification::None); + } + { + std::optional opt; + assert(opt.value_or({}).qual_ == Qualification::None); + } + + assert( + (std::optional{} = {QualDistinction{}}).value().qual_ == Qualification::None); + assert((std::optional{} = {QualDistinction{}}).value().qual_ + == Qualification::None); + { + std::optional opt{std::in_place}; + assert((opt = {QualDistinction{}}).value().qual_ == Qualification::None); + opt.reset(); + assert((opt = {QualDistinction{}}).value().qual_ == Qualification::None); + } + { + std::optional opt{std::in_place}; + assert((opt = {QualDistinction{}}).value().qual_ == Qualification::None); + opt.reset(); + assert((opt = {QualDistinction{}}).value().qual_ == Qualification::None); + } + + return true; + } + + static_assert(test_value_or()); +#if _HAS_CXX20 + static_assert(test_assignment()); +#endif // _HAS_CXX20 + + void run_test() { + test_value_or(); + test_assignment(); + test_volatile(); + } + } // namespace lwg3886 + namespace vso406124 { // Defend against regression of VSO-406124 void run_test() { @@ -8719,6 +8856,7 @@ int main() { optional_includes_initializer_list::run_test(); msvc::lwg3836::run_test(); + msvc::lwg3886::run_test(); msvc::vso406124::run_test(); msvc::vso508126::run_test(); diff --git a/tests/std/tests/P0220R1_string_view/test.cpp b/tests/std/tests/P0220R1_string_view/test.cpp index a03ff3a220d..dac4ec93ae0 100644 --- a/tests/std/tests/P0220R1_string_view/test.cpp +++ b/tests/std/tests/P0220R1_string_view/test.cpp @@ -1284,20 +1284,14 @@ namespace test_lwg_3950 { template concept characterized_traits = requires { typename Traits::is_characterized; }; -#ifdef __clang__ // TRANSITION, LLVM-75404 -#define CONST_PARAM const -#else // ^^^ workaround / no workaround vvv -#define CONST_PARAM -#endif // ^^^ no workaround ^^^ - template - constexpr bool operator==(CONST_PARAM basic_string_view x, - CONST_PARAM type_identity_t> y) noexcept { + constexpr bool operator==( + basic_string_view x, type_identity_t> y) noexcept { return x.size() == y.size() && x.compare(y) == 0; } template - constexpr get_string_comparison_category_t operator<=>(CONST_PARAM basic_string_view x, - CONST_PARAM type_identity_t> y) noexcept { + constexpr get_string_comparison_category_t operator<=>( + basic_string_view x, type_identity_t> y) noexcept { return static_cast>(x.compare(y) <=> 0); } diff --git a/tests/std/tests/P0288R9_move_only_function/test.cpp b/tests/std/tests/P0288R9_move_only_function/test.cpp index cb3dd580090..e0c30ad480f 100644 --- a/tests/std/tests/P0288R9_move_only_function/test.cpp +++ b/tests/std/tests/P0288R9_move_only_function/test.cpp @@ -214,16 +214,17 @@ void test_assign() { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wself-move" #endif // __clang__ +#pragma warning(push) +#pragma warning(disable : 26800) // use a moved-from object { test_function_t f1{small_callable{}}; test_function_t f2{large_callable{}}; f1 = move(f1); // deliberate self-move as a test case -#pragma warning(suppress : 26800) // use a moved-from object assert(f1(23, x) == 38); f2 = move(f2); // deliberate self-move as a test case -#pragma warning(suppress : 26800) // use a moved-from object assert(f2(23, x) == 39); } +#pragma warning(pop) #ifdef __clang__ #pragma clang diagnostic pop #endif // __clang__ @@ -294,9 +295,11 @@ void test_empty() { assert(nullptr == no_callable); test_function_t no_callable_moved = move(no_callable); -#pragma warning(suppress : 26800) // use a moved-from object +#pragma warning(push) +#pragma warning(disable : 26800) // use a moved-from object assert(!no_callable); assert(no_callable == nullptr); +#pragma warning(pop) assert(!no_callable_moved); assert(no_callable_moved == nullptr); } @@ -339,9 +342,11 @@ void test_inner() { move_only_function f1(nullptr); move_only_function f2 = move(f1); assert(!f2); -#pragma warning(suppress : 26800) // use a moved-from object +#pragma warning(push) +#pragma warning(disable : 26800) // use a moved-from object f2 = move(f1); assert(!f1); +#pragma warning(pop) } @@ -498,8 +503,10 @@ static_assert(is_same_v::result bool fail_allocations = false; -#pragma warning(suppress : 28251) // Inconsistent annotation for 'new': this instance has no annotations. +#pragma warning(push) +#pragma warning(disable : 28251) // Inconsistent annotation for 'new': this instance has no annotations. void* operator new(size_t size) { +#pragma warning(pop) if (fail_allocations) { throw bad_alloc{}; } diff --git a/tests/std/tests/P0323R12_expected/test.cpp b/tests/std/tests/P0323R12_expected/test.cpp index b964b554c8f..37476de98b0 100644 --- a/tests/std/tests/P0323R12_expected/test.cpp +++ b/tests/std/tests/P0323R12_expected/test.cpp @@ -173,7 +173,8 @@ namespace test_unexpected { namespace test_unexpect { auto copy = unexpect; static_assert(is_same_v); - static_assert(is_trivial_v); + static_assert(is_trivially_copyable_v); + static_assert(is_trivially_default_constructible_v); static_assert(is_empty_v); } // namespace test_unexpect @@ -2315,6 +2316,133 @@ void test_lwg_3843() { } } +// Test LWG-3886: "Monad mo' problems (in optional and expected)" + +enum class Qualification { + None, + Const, + Volatile, + ConstVolatile, +}; + +template +constexpr Qualification CvQualOf = + is_const_v> + ? (is_volatile_v> ? Qualification::ConstVolatile : Qualification::Const) + : (is_volatile_v> ? Qualification::Volatile : Qualification::None); + +struct QualDistinction { + QualDistinction() = default; + + constexpr QualDistinction(QualDistinction&&) noexcept : qual_{Qualification::None} {} + constexpr QualDistinction(const QualDistinction&) noexcept : qual_{Qualification::Const} {} + template + requires is_same_v, QualDistinction> + constexpr QualDistinction(T&&) noexcept : qual_{CvQualOf} {} + + constexpr QualDistinction& operator=(QualDistinction&&) noexcept { + qual_ = Qualification::None; + return *this; + } + constexpr QualDistinction& operator=(const QualDistinction&) noexcept { + qual_ = Qualification::Const; + return *this; + } + template + requires is_same_v, QualDistinction> + constexpr QualDistinction& operator=(T&&) noexcept { + qual_ = CvQualOf; + return *this; + } + template + requires is_same_v, QualDistinction> + constexpr const QualDistinction& operator=(T&&) const noexcept { + qual_ = CvQualOf; + return *this; + } + template + requires is_same_v, QualDistinction> + volatile QualDistinction& operator=(T&&) volatile noexcept { + qual_ = CvQualOf; + return *this; + } + template + requires is_same_v, QualDistinction> + const volatile QualDistinction& operator=(T&&) const volatile noexcept { + qual_ = CvQualOf; + return *this; + } + + mutable Qualification qual_ = Qualification::None; +}; + +constexpr bool test_lwg_3886() { + assert((expected{unexpect}.value_or({}).qual_ == Qualification::None)); + { + expected ex{unexpect}; + assert(ex.value_or({}).qual_ == Qualification::None); + } + assert((expected{unexpect} = {QualDistinction{}}).value().qual_ == Qualification::None); + { + expected ex{in_place}; + assert((ex = {QualDistinction{}}).value().qual_ == Qualification::None); + ex = unexpected{'*'}; + assert((ex = {QualDistinction{}}).value().qual_ == Qualification::None); + } + + assert((expected{unexpect}.value_or({}).qual_ == Qualification::None)); + { + expected ex{unexpect}; + assert(ex.value_or({}).qual_ == Qualification::None); + } +#if 0 // TRANSITION, LWG-3891 + assert( + (expected{unexpect} = {QualDistinction{}}).value().qual_ == Qualification::None); + { + expected ex{in_place}; + assert((ex = {QualDistinction{}}).value().qual_ == Qualification::None); + ex = unexpected{'*'}; + assert((ex = {QualDistinction{}}).value().qual_ == Qualification::None); + } +#endif // ^^^ no workaround ^^^ + + return true; +} + +void test_lwg_3886_volatile() { + assert((expected{unexpect}.value_or({}).qual_ == Qualification::None)); + { + expected ex{unexpect}; + assert(ex.value_or({}).qual_ == Qualification::None); + } +#if 0 // TRANSITION, LWG-3891 + assert((expected{unexpect} = {QualDistinction{}}).value().qual_ + == Qualification::None); + { + expected ex{in_place}; + assert((ex = {QualDistinction{}}).value().qual_ == Qualification::None); + ex = unexpected{'*'}; + assert((ex = {QualDistinction{}}).value().qual_ == Qualification::None); + } +#endif // ^^^ no workaround ^^^ + + assert((expected{unexpect}.value_or({}).qual_ == Qualification::None)); + { + expected ex{unexpect}; + assert(ex.value_or({}).qual_ == Qualification::None); + } +#if 0 // TRANSITION, LWG-3891 + assert((expected{unexpect} = {QualDistinction{}}).value().qual_ + == Qualification::None); + { + expected ex{in_place}; + assert((ex = {QualDistinction{}}).value().qual_ == Qualification::None); + ex = unexpected{'*'}; + assert((ex = {QualDistinction{}}).value().qual_ == Qualification::None); + } +#endif // ^^^ no workaround ^^^ +} + // Test GH-4011: these predicates triggered constraint recursion. static_assert(copyable>); static_assert(copyable>); @@ -2348,24 +2476,17 @@ static_assert(test_inherited_constructors()); template struct ambiguating_expected_copy_constructor_caller { struct const_lvalue_taker { - const_lvalue_taker(const expected&) {} + const_lvalue_taker(const expected&); }; - void operator()(expected) {} - void operator()(const_lvalue_taker) {} + void operator()(expected); + void operator()(const_lvalue_taker); }; template struct ambiguating_expected_assignment_source { - operator const expected&() && { - return ex; - } - - operator expected&&() && { - return move(ex); - } - - expected ex; + operator const expected&() &&; + operator expected&&() &&; }; struct move_only { @@ -2384,9 +2505,11 @@ static_assert( #ifndef __EDG__ // TRANSITION, VSO-1601179 static_assert(!is_assignable_v&, ambiguating_expected_assignment_source>); static_assert(!is_assignable_v&, ambiguating_expected_assignment_source>); -#endif // ^^^ no workaround ^^^ static_assert(!is_assignable_v&, ambiguating_expected_assignment_source>); static_assert(!is_assignable_v&, ambiguating_expected_assignment_source>); +#endif // ^^^ no workaround ^^^ + +static_assert(test_lwg_3886()); int main() { test_unexpected::test_all(); @@ -2404,5 +2527,7 @@ int main() { test_reinit_regression(); test_lwg_3843(); + test_lwg_3886(); + test_lwg_3886_volatile(); test_inherited_constructors(); } diff --git a/tests/std/tests/P0414R2_shared_ptr_for_arrays/test.cpp b/tests/std/tests/P0414R2_shared_ptr_for_arrays/test.cpp index e3c2f6570e5..221df456f34 100644 --- a/tests/std/tests/P0414R2_shared_ptr_for_arrays/test.cpp +++ b/tests/std/tests/P0414R2_shared_ptr_for_arrays/test.cpp @@ -236,11 +236,11 @@ void test_shared_ptr_all_copy_ctors() { const shared_ptr&>); // GOOD: known-to-unknown is compatible STATIC_ASSERT(!is_constructible_v, - const shared_ptr&>); // BAD: unknown-to-known isn't allowed + const shared_ptr&>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT( is_nothrow_constructible_v, const shared_ptr&>); // GOOD: adds const STATIC_ASSERT(!is_constructible_v, - const shared_ptr&>); // BAD: unknown-to-known isn't allowed + const shared_ptr&>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(is_nothrow_constructible_v, const shared_ptr&>); // GOOD: same (plain, not converting) @@ -297,7 +297,7 @@ void test_shared_ptr_all_move_ctors() { !is_constructible_v, shared_ptr>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(is_nothrow_constructible_v, shared_ptr>); // GOOD: adds const STATIC_ASSERT(!is_constructible_v, - shared_ptr>); // BAD: unknown-to-known isn't allowed + shared_ptr>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(is_nothrow_constructible_v, shared_ptr>); // GOOD: same (plain, not converting) @@ -351,10 +351,10 @@ void test_shared_ptr_weak_ctor() { const weak_ptr&>); // GOOD: known-to-unknown is compatible STATIC_ASSERT(!is_constructible_v, - const weak_ptr&>); // BAD: unknown-to-known isn't allowed + const weak_ptr&>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(is_constructible_v, const weak_ptr&>); // GOOD: adds const STATIC_ASSERT(!is_constructible_v, - const weak_ptr&>); // BAD: unknown-to-known isn't allowed + const weak_ptr&>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(is_constructible_v, const weak_ptr&>); // GOOD: same impl_shared_ptr_weak_ctor(); @@ -406,7 +406,7 @@ void test_shared_ptr_unique_ctor() { STATIC_ASSERT( !is_constructible_v, unique_ptr>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(!is_constructible_v, - unique_ptr>); // BAD: unknown-to-known isn't allowed + unique_ptr>); // BAD: unknown-to-known isn't allowed impl_shared_ptr_unique_ctor(); impl_shared_ptr_unique_ctor(); @@ -678,11 +678,11 @@ void test_weak_ptr_all_copy_ctors_and_shared_ctor() { const weak_ptr&>); // GOOD: known-to-unknown is compatible STATIC_ASSERT(!is_constructible_v, - const weak_ptr&>); // BAD: unknown-to-known isn't allowed + const weak_ptr&>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT( is_nothrow_constructible_v, const weak_ptr&>); // GOOD: adds const STATIC_ASSERT(!is_constructible_v, - const weak_ptr&>); // BAD: unknown-to-known isn't allowed + const weak_ptr&>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(is_nothrow_constructible_v, const weak_ptr&>); // GOOD: same (plain, not converting) @@ -708,11 +708,11 @@ void test_weak_ptr_all_copy_ctors_and_shared_ctor() { const shared_ptr&>); // GOOD: known-to-unknown is compatible STATIC_ASSERT(!is_constructible_v, - const shared_ptr&>); // BAD: unknown-to-known isn't allowed + const shared_ptr&>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT( is_nothrow_constructible_v, const shared_ptr&>); // GOOD: adds const STATIC_ASSERT(!is_constructible_v, - const shared_ptr&>); // BAD: unknown-to-known isn't allowed + const shared_ptr&>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT( is_nothrow_constructible_v, const shared_ptr&>); // GOOD: same @@ -768,7 +768,7 @@ void test_weak_ptr_all_move_ctors() { !is_constructible_v, weak_ptr>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(is_nothrow_constructible_v, weak_ptr>); // GOOD: adds const STATIC_ASSERT(!is_constructible_v, - weak_ptr>); // BAD: unknown-to-known isn't allowed + weak_ptr>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(is_nothrow_constructible_v, weak_ptr>); // GOOD: same (plain, not converting) diff --git a/tests/std/tests/P0433R2_deduction_guides/test.cpp b/tests/std/tests/P0433R2_deduction_guides/test.cpp index 02de419f829..e4f7407ca47 100644 --- a/tests/std/tests/P0433R2_deduction_guides/test.cpp +++ b/tests/std/tests/P0433R2_deduction_guides/test.cpp @@ -710,8 +710,7 @@ void test_set_or_multiset() { } template