diff --git a/CMakeLists.txt b/CMakeLists.txt index 38b443326e3..f85527c87f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -cmake_minimum_required(VERSION 3.28.0) +cmake_minimum_required(VERSION 3.29.0) set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) project(msvc_standard_libraries LANGUAGES CXX) diff --git a/README.md b/README.md index 92a1d1062b9..56cd3ab20b1 100644 --- a/README.md +++ b/README.md @@ -141,11 +141,11 @@ 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.11 Preview 2 or later. +1. Install Visual Studio 2022 17.11 Preview 3 or later. * Select "Windows 11 SDK (10.0.22621.0)" in the VS Installer. * We recommend selecting "C++ CMake tools for Windows" in the VS Installer. This will ensure that you're using supported versions of CMake and Ninja. - * Otherwise, install [CMake][] 3.28.0 or later, and [Ninja][] 1.11.0 or later. + * Otherwise, install [CMake][] 3.29.0 or later, and [Ninja][] 1.11.0 or later. * Make sure [Python][] 3.12 or later is available to CMake. 2. Open Visual Studio, and choose the "Clone or check out code" option. Enter the URL of this repository, `https://github.com/microsoft/STL`. @@ -156,11 +156,11 @@ 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.11 Preview 2 or later. +1. Install Visual Studio 2022 17.11 Preview 3 or later. * Select "Windows 11 SDK (10.0.22621.0)" in the VS Installer. * We recommend selecting "C++ CMake tools for Windows" in the VS Installer. This will ensure that you're using supported versions of CMake and Ninja. - * Otherwise, install [CMake][] 3.28.0 or later, and [Ninja][] 1.11.0 or later. + * Otherwise, install [CMake][] 3.29.0 or later, and [Ninja][] 1.11.0 or later. * Make sure [Python][] 3.12 or later is available to CMake. 2. Open a command prompt. 3. Change directories to a location where you'd like a clone of this STL repository. diff --git a/azure-devops/config.yml b/azure-devops/config.yml index 43ac66c6059..a7da64abd9c 100644 --- a/azure-devops/config.yml +++ b/azure-devops/config.yml @@ -5,7 +5,7 @@ variables: - name: poolName - value: 'StlBuild-2024-06-11T1315-Pool' + value: 'StlBuild-2024-07-09T1614-Pool' readonly: true - name: poolDemands value: 'EnableSpotVM -equals false' diff --git a/azure-devops/create-1es-hosted-pool.ps1 b/azure-devops/create-1es-hosted-pool.ps1 index c996e8d74ba..307c511a7c8 100644 --- a/azure-devops/create-1es-hosted-pool.ps1 +++ b/azure-devops/create-1es-hosted-pool.ps1 @@ -13,7 +13,7 @@ $ErrorActionPreference = 'Stop' $CurrentDate = Get-Date -$Location = 'eastus' +$Location = 'eastus2' $VMSize = 'Standard_D32ads_v5' $ProtoVMName = 'PROTOTYPE' $ImagePublisher = 'MicrosoftWindowsServer' diff --git a/azure-devops/provision-image.ps1 b/azure-devops/provision-image.ps1 index 826fa4bfea5..097bc2fd53a 100644 --- a/azure-devops/provision-image.ps1 +++ b/azure-devops/provision-image.ps1 @@ -40,7 +40,7 @@ foreach ($workload in $VisualStudioWorkloads) { } # https://github.com/PowerShell/PowerShell/releases/latest -$PowerShellUrl = 'https://github.com/PowerShell/PowerShell/releases/download/v7.4.2/PowerShell-7.4.2-win-x64.msi' +$PowerShellUrl = 'https://github.com/PowerShell/PowerShell/releases/download/v7.4.3/PowerShell-7.4.3-win-x64.msi' $PowerShellArgs = @('/quiet', '/norestart') $PythonUrl = 'https://www.python.org/ftp/python/3.12.4/python-3.12.4-amd64.exe' diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt index bb6ebbf4030..32c6e1925fa 100644 --- a/benchmarks/CMakeLists.txt +++ b/benchmarks/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -cmake_minimum_required(VERSION 3.28.0) +cmake_minimum_required(VERSION 3.29.0) project(msvc_standard_libraries_benchmarks LANGUAGES CXX) if(DEFINED STL_BINARY_DIR) diff --git a/benchmarks/src/bitset_to_string.cpp b/benchmarks/src/bitset_to_string.cpp index c5f012c6a18..5fc88147839 100644 --- a/benchmarks/src/bitset_to_string.cpp +++ b/benchmarks/src/bitset_to_string.cpp @@ -13,29 +13,40 @@ using namespace std; namespace { - const auto random_bits = [] { + template + auto random_bits_init() { mt19937_64 rnd{}; - array arr; + array arr; for (auto& d : arr) { d = rnd(); } return arr; - }(); + } + + template + const auto random_bits = random_bits_init(); template void BM_bitset_to_string(benchmark::State& state) { + static_assert(N <= 64); + for (auto _ : state) { - for (const auto& bits : random_bits) { + for (const auto& bits : random_bits<>) { + benchmark::DoNotOptimize(bits); bitset bs{bits}; benchmark::DoNotOptimize(bs.to_string()); } } } - template + template void BM_bitset_to_string_large_single(benchmark::State& state) { - const auto large_bitset = bit_cast>(random_bits); + static_assert(N % 64 == 0 && N >= 64); + const auto& bitset_data = random_bits; + + const auto large_bitset = bit_cast>(bitset_data); for (auto _ : state) { + benchmark::DoNotOptimize(large_bitset); benchmark::DoNotOptimize(large_bitset.to_string()); } } @@ -43,11 +54,11 @@ namespace { BENCHMARK(BM_bitset_to_string<15, char>); BENCHMARK(BM_bitset_to_string<64, char>); -BENCHMARK(BM_bitset_to_string<512, char>); -BENCHMARK(BM_bitset_to_string_large_single); +BENCHMARK(BM_bitset_to_string_large_single<512, char>); +BENCHMARK(BM_bitset_to_string_large_single<2048, char>); BENCHMARK(BM_bitset_to_string<7, wchar_t>); BENCHMARK(BM_bitset_to_string<64, wchar_t>); -BENCHMARK(BM_bitset_to_string<512, wchar_t>); -BENCHMARK(BM_bitset_to_string_large_single); +BENCHMARK(BM_bitset_to_string_large_single<512, wchar_t>); +BENCHMARK(BM_bitset_to_string_large_single<2048, wchar_t>); BENCHMARK_MAIN(); diff --git a/stl/inc/__msvc_bit_utils.hpp b/stl/inc/__msvc_bit_utils.hpp index 7537edb3ef3..eb86c43d0f4 100644 --- a/stl/inc/__msvc_bit_utils.hpp +++ b/stl/inc/__msvc_bit_utils.hpp @@ -300,9 +300,8 @@ _NODISCARD int _Checked_x86_x64_countr_zero(const _Ty _Val) noexcept { #endif // _HAS_TZCNT_BSF_INTRINSICS -// TRANSITION, remove `_MSC_VER > 1940` check after MSVC-internal toolset update -#if (defined(_M_IX86) || defined(_M_X64) || (defined(_M_ARM64) && _MSC_VER > 1940)) && !defined(_M_CEE_PURE) \ - && !defined(__CUDACC__) && !defined(__INTEL_COMPILER) +#if (defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64)) && !defined(_M_CEE_PURE) && !defined(__CUDACC__) \ + && !defined(__INTEL_COMPILER) #define _HAS_POPCNT_INTRINSICS 1 #if defined(__AVX__) || defined(_M_ARM64) || defined(_M_ARM64EC) #define _POPCNT_INTRINSICS_ALWAYS_AVAILABLE 1 diff --git a/stl/inc/__msvc_formatter.hpp b/stl/inc/__msvc_formatter.hpp index bcf1f6e689e..5ff1bea2f4b 100644 --- a/stl/inc/__msvc_formatter.hpp +++ b/stl/inc/__msvc_formatter.hpp @@ -271,6 +271,41 @@ struct formatter, _CharT> }; #if _HAS_CXX23 +template <> +struct formatter { + formatter() = delete; + formatter(const formatter&) = delete; + formatter& operator=(const formatter&) = delete; +}; + +template <> +struct formatter { + formatter() = delete; + formatter(const formatter&) = delete; + formatter& operator=(const formatter&) = delete; +}; + +template +struct formatter { + formatter() = delete; + formatter(const formatter&) = delete; + formatter& operator=(const formatter&) = delete; +}; + +template +struct formatter, wchar_t> { + formatter() = delete; + formatter(const formatter&) = delete; + formatter& operator=(const formatter&) = delete; +}; + +template +struct formatter, wchar_t> { + formatter() = delete; + formatter(const formatter&) = delete; + formatter& operator=(const formatter&) = delete; +}; + _EXPORT_STD enum class range_format { disabled, map, set, sequence, string, debug_string }; template diff --git a/stl/inc/__msvc_int128.hpp b/stl/inc/__msvc_int128.hpp index 306bb9e8b03..cef5bd87c0a 100644 --- a/stl/inc/__msvc_int128.hpp +++ b/stl/inc/__msvc_int128.hpp @@ -328,18 +328,18 @@ struct } #if _HAS_CXX20 - _NODISCARD_FRIEND constexpr bool operator==(const _Base128&, const _Base128&) noexcept = default; + _NODISCARD friend constexpr bool operator==(const _Base128&, const _Base128&) noexcept = default; #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv - _NODISCARD_FRIEND constexpr bool operator==(const _Base128& _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr bool operator==(const _Base128& _Left, const _Base128& _Right) noexcept { return _Left._Word[0] == _Right._Word[0] && _Left._Word[1] == _Right._Word[1]; } - _NODISCARD_FRIEND constexpr bool operator!=(const _Base128& _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr bool operator!=(const _Base128& _Left, const _Base128& _Right) noexcept { return !(_Left == _Right); } #endif // ^^^ !_HAS_CXX20 ^^^ - _NODISCARD_FRIEND constexpr bool operator<(const _Base128& _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr bool operator<(const _Base128& _Left, const _Base128& _Right) noexcept { if (_Left._Word[1] < _Right._Word[1]) { return true; } @@ -349,23 +349,23 @@ struct } return _Left._Word[0] < _Right._Word[0]; } - _NODISCARD_FRIEND constexpr bool operator>(const _Base128& _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr bool operator>(const _Base128& _Left, const _Base128& _Right) noexcept { return _Right < _Left; } - _NODISCARD_FRIEND constexpr bool operator<=(const _Base128& _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr bool operator<=(const _Base128& _Left, const _Base128& _Right) noexcept { return !(_Right < _Left); } - _NODISCARD_FRIEND constexpr bool operator>=(const _Base128& _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr bool operator>=(const _Base128& _Left, const _Base128& _Right) noexcept { return !(_Left < _Right); } _TEMPLATE_CLASS_INTEGRAL(_Ty) - _NODISCARD_FRIEND constexpr _Ty operator<<(const _Ty _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr _Ty operator<<(const _Ty _Left, const _Base128& _Right) noexcept { return _Left << _Right._Word[0]; } _TEMPLATE_CLASS_INTEGRAL(_Ty) - _NODISCARD_FRIEND constexpr _Ty operator>>(const _Ty _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr _Ty operator>>(const _Ty _Left, const _Base128& _Right) noexcept { return _Left >> _Right._Word[0]; } @@ -720,7 +720,7 @@ struct _Unsigned128 : _Base128 { } #if _HAS_CXX20 - _NODISCARD_FRIEND constexpr strong_ordering operator<=>( + _NODISCARD friend constexpr strong_ordering operator<=>( const _Unsigned128& _Left, const _Unsigned128& _Right) noexcept { strong_ordering _Ord = _Left._Word[1] <=> _Right._Word[1]; if (_Ord == strong_ordering::equal) { @@ -729,7 +729,7 @@ struct _Unsigned128 : _Base128 { return _Ord; } #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv - _NODISCARD_FRIEND constexpr bool operator<(const _Unsigned128& _Left, const _Unsigned128& _Right) noexcept { + _NODISCARD friend constexpr bool operator<(const _Unsigned128& _Left, const _Unsigned128& _Right) noexcept { if (_Left._Word[1] < _Right._Word[1]) { return true; } @@ -741,20 +741,20 @@ struct _Unsigned128 : _Base128 { return _Left._Word[0] < _Right._Word[0]; } - _NODISCARD_FRIEND constexpr bool operator>(const _Unsigned128& _Left, const _Unsigned128& _Right) noexcept { + _NODISCARD friend constexpr bool operator>(const _Unsigned128& _Left, const _Unsigned128& _Right) noexcept { return _Right < _Left; } - _NODISCARD_FRIEND constexpr bool operator<=(const _Unsigned128& _Left, const _Unsigned128& _Right) noexcept { + _NODISCARD friend constexpr bool operator<=(const _Unsigned128& _Left, const _Unsigned128& _Right) noexcept { return !(_Right < _Left); } - _NODISCARD_FRIEND constexpr bool operator>=(const _Unsigned128& _Left, const _Unsigned128& _Right) noexcept { + _NODISCARD friend constexpr bool operator>=(const _Unsigned128& _Left, const _Unsigned128& _Right) noexcept { return !(_Left < _Right); } #endif // ^^^ !_HAS_CXX20 ^^^ - _NODISCARD_FRIEND constexpr _Unsigned128 operator<<(const _Unsigned128& _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr _Unsigned128 operator<<(const _Unsigned128& _Left, const _Base128& _Right) noexcept { auto _Tmp{_Left}; _Tmp._Left_shift(static_cast(_Right._Word[0])); return _Tmp; @@ -770,7 +770,7 @@ struct _Unsigned128 : _Base128 { return *this; } - _NODISCARD_FRIEND constexpr _Unsigned128 operator>>(const _Unsigned128& _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr _Unsigned128 operator>>(const _Unsigned128& _Left, const _Base128& _Right) noexcept { auto _Tmp{_Left}; _Tmp._Unsigned_right_shift(static_cast(_Right._Word[0])); return _Tmp; @@ -822,7 +822,7 @@ struct _Unsigned128 : _Base128 { return _Unsigned128{~_Word[0], ~_Word[1]}; } - _NODISCARD_FRIEND constexpr _Unsigned128 operator+(const _Base128& _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr _Unsigned128 operator+(const _Base128& _Left, const _Base128& _Right) noexcept { _Unsigned128 _Result; const auto _Carry = _AddCarry64(0, _Left._Word[0], _Right._Word[0], _Result._Word[0]); _AddCarry64(_Carry, _Left._Word[1], _Right._Word[1], _Result._Word[1]); @@ -840,7 +840,7 @@ struct _Unsigned128 : _Base128 { return _Left; } - _NODISCARD_FRIEND constexpr _Unsigned128 operator-(const _Base128& _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr _Unsigned128 operator-(const _Base128& _Left, const _Base128& _Right) noexcept { _Unsigned128 _Result; const auto _Borrow = _SubBorrow64(0, _Left._Word[0], _Right._Word[0], _Result._Word[0]); _SubBorrow64(_Borrow, _Left._Word[1], _Right._Word[1], _Result._Word[1]); @@ -858,7 +858,7 @@ struct _Unsigned128 : _Base128 { return _Left; } - _NODISCARD_FRIEND constexpr _Unsigned128 operator*(const _Base128& _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr _Unsigned128 operator*(const _Base128& _Left, const _Base128& _Right) noexcept { return _Unsigned128{_Base128::_Multiply(_Left, _Right)}; } @@ -873,7 +873,7 @@ struct _Unsigned128 : _Base128 { } _TEMPLATE_CLASS_INTEGRAL(_Ty) - _NODISCARD_FRIEND constexpr _Unsigned128 operator/(const _Unsigned128& _Num, const _Ty _Den) noexcept { + _NODISCARD friend constexpr _Unsigned128 operator/(const _Unsigned128& _Num, const _Ty _Den) noexcept { #if !_STL_128_DIV_INTRINSICS if constexpr (sizeof(_Ty) <= 4) { return _Unsigned128{_Base128::_Divide(_Num, static_cast(_Den))}; @@ -883,7 +883,7 @@ struct _Unsigned128 : _Base128 { return _Unsigned128{_Base128::_Divide(_Num, static_cast(_Den))}; } } - _NODISCARD_FRIEND constexpr _Unsigned128 operator/(const _Base128& _Num, const _Base128& _Den) noexcept { + _NODISCARD friend constexpr _Unsigned128 operator/(const _Base128& _Num, const _Base128& _Den) noexcept { return _Unsigned128{_Base128::_Divide(_Num, _Den)}; } @@ -914,7 +914,7 @@ struct _Unsigned128 : _Base128 { } _TEMPLATE_CLASS_INTEGRAL(_Ty) - _NODISCARD_FRIEND constexpr _Unsigned128 operator%(const _Base128& _Num, const _Ty _Den) noexcept { + _NODISCARD friend constexpr _Unsigned128 operator%(const _Base128& _Num, const _Ty _Den) noexcept { #if !_STL_128_DIV_INTRINSICS if constexpr (sizeof(_Ty) <= 4) { return _Unsigned128{_Base128::_Modulo(_Num, static_cast(_Den))}; @@ -924,7 +924,7 @@ struct _Unsigned128 : _Base128 { return _Unsigned128{_Base128::_Modulo(_Num, static_cast(_Den))}; } } - _NODISCARD_FRIEND constexpr _Unsigned128 operator%(const _Base128& _Num, const _Base128& _Den) noexcept { + _NODISCARD friend constexpr _Unsigned128 operator%(const _Base128& _Num, const _Base128& _Den) noexcept { return _Unsigned128{_Base128::_Modulo(_Num, _Den)}; } @@ -945,7 +945,7 @@ struct _Unsigned128 : _Base128 { return _Left; } - _NODISCARD_FRIEND constexpr _Unsigned128 operator&(const _Base128& _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr _Unsigned128 operator&(const _Base128& _Left, const _Base128& _Right) noexcept { return _Unsigned128{_Left._Word[0] & _Right._Word[0], _Left._Word[1] & _Right._Word[1]}; } @@ -955,7 +955,7 @@ struct _Unsigned128 : _Base128 { return *this; } - _NODISCARD_FRIEND constexpr _Unsigned128 operator^(const _Base128& _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr _Unsigned128 operator^(const _Base128& _Left, const _Base128& _Right) noexcept { return _Unsigned128{_Left._Word[0] ^ _Right._Word[0], _Left._Word[1] ^ _Right._Word[1]}; } @@ -965,7 +965,7 @@ struct _Unsigned128 : _Base128 { return *this; } - _NODISCARD_FRIEND constexpr _Unsigned128 operator|(const _Base128& _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr _Unsigned128 operator|(const _Base128& _Left, const _Base128& _Right) noexcept { return _Unsigned128{_Left._Word[0] | _Right._Word[0], _Left._Word[1] | _Right._Word[1]}; } @@ -1037,7 +1037,7 @@ struct _Signed128 : _Base128 { } #if _HAS_CXX20 - _NODISCARD_FRIEND constexpr strong_ordering operator<=>( + _NODISCARD friend constexpr strong_ordering operator<=>( const _Signed128& _Left, const _Signed128& _Right) noexcept { strong_ordering _Ord = static_cast(_Left._Word[1]) <=> static_cast(_Right._Word[1]); if (_Ord == strong_ordering::equal) { @@ -1046,7 +1046,7 @@ struct _Signed128 : _Base128 { return _Ord; } #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv - _NODISCARD_FRIEND constexpr bool operator<(const _Signed128& _Left, const _Signed128& _Right) noexcept { + _NODISCARD friend constexpr bool operator<(const _Signed128& _Left, const _Signed128& _Right) noexcept { if (static_cast(_Left._Word[1]) < static_cast(_Right._Word[1])) { return true; } @@ -1058,20 +1058,20 @@ struct _Signed128 : _Base128 { return _Left._Word[0] < _Right._Word[0]; } - _NODISCARD_FRIEND constexpr bool operator>(const _Signed128& _Left, const _Signed128& _Right) noexcept { + _NODISCARD friend constexpr bool operator>(const _Signed128& _Left, const _Signed128& _Right) noexcept { return _Right < _Left; } - _NODISCARD_FRIEND constexpr bool operator<=(const _Signed128& _Left, const _Signed128& _Right) noexcept { + _NODISCARD friend constexpr bool operator<=(const _Signed128& _Left, const _Signed128& _Right) noexcept { return !(_Right < _Left); } - _NODISCARD_FRIEND constexpr bool operator>=(const _Signed128& _Left, const _Signed128& _Right) noexcept { + _NODISCARD friend constexpr bool operator>=(const _Signed128& _Left, const _Signed128& _Right) noexcept { return !(_Left < _Right); } #endif // ^^^ !_HAS_CXX20 ^^^ - _NODISCARD_FRIEND constexpr _Signed128 operator<<(const _Signed128& _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr _Signed128 operator<<(const _Signed128& _Left, const _Base128& _Right) noexcept { auto _Tmp{_Left}; _Tmp._Left_shift(static_cast(_Right._Word[0])); return _Tmp; @@ -1110,7 +1110,7 @@ struct _Signed128 : _Base128 { _Word[1] = static_cast(static_cast(_Word[1]) >> _Count); } - _NODISCARD_FRIEND constexpr _Signed128 operator>>(const _Signed128& _Left, const _Base128& _Right) noexcept { + _NODISCARD friend constexpr _Signed128 operator>>(const _Signed128& _Left, const _Base128& _Right) noexcept { auto _Tmp{_Left}; _Tmp._Signed_right_shift(static_cast(_Right._Word[0])); return _Tmp; @@ -1162,7 +1162,7 @@ struct _Signed128 : _Base128 { return _Signed128{~_Word[0], ~_Word[1]}; } - _NODISCARD_FRIEND constexpr _Signed128 operator+(const _Signed128& _Left, const _Signed128& _Right) noexcept { + _NODISCARD friend constexpr _Signed128 operator+(const _Signed128& _Left, const _Signed128& _Right) noexcept { _Signed128 _Result; const auto _Carry = _AddCarry64(0, _Left._Word[0], _Right._Word[0], _Result._Word[0]); _AddCarry64(_Carry, _Left._Word[1], _Right._Word[1], _Result._Word[1]); @@ -1180,7 +1180,7 @@ struct _Signed128 : _Base128 { return _Left; } - _NODISCARD_FRIEND constexpr _Signed128 operator-(const _Signed128& _Left, const _Signed128& _Right) noexcept { + _NODISCARD friend constexpr _Signed128 operator-(const _Signed128& _Left, const _Signed128& _Right) noexcept { _Signed128 _Result; const auto _Borrow = _SubBorrow64(0, _Left._Word[0], _Right._Word[0], _Result._Word[0]); _SubBorrow64(_Borrow, _Left._Word[1], _Right._Word[1], _Result._Word[1]); @@ -1205,7 +1205,7 @@ struct _Signed128 : _Base128 { } } - _NODISCARD_FRIEND constexpr _Signed128 operator*(_Signed128 _Left, _Signed128 _Right) noexcept { + _NODISCARD friend constexpr _Signed128 operator*(_Signed128 _Left, _Signed128 _Right) noexcept { bool _Negative = false; _Left._Strip_negative(_Negative); _Right._Strip_negative(_Negative); @@ -1236,7 +1236,7 @@ struct _Signed128 : _Base128 { } _TEMPLATE_CLASS_INTEGRAL(_Ty) - _NODISCARD_FRIEND constexpr _Signed128 operator/(_Signed128 _Num, _Ty _Den) noexcept { + _NODISCARD friend constexpr _Signed128 operator/(_Signed128 _Num, _Ty _Den) noexcept { bool _Negative = false; _Num._Strip_negative(_Negative); if constexpr (is_signed_v<_Ty>) { @@ -1261,7 +1261,7 @@ struct _Signed128 : _Base128 { } return _Result; } - _NODISCARD_FRIEND constexpr _Signed128 operator/(_Signed128 _Num, _Signed128 _Den) noexcept { + _NODISCARD friend constexpr _Signed128 operator/(_Signed128 _Num, _Signed128 _Den) noexcept { bool _Negative = false; _Num._Strip_negative(_Negative); _Den._Strip_negative(_Negative); @@ -1291,7 +1291,7 @@ struct _Signed128 : _Base128 { return _Left; } - _NODISCARD_FRIEND constexpr _Signed128 operator%(_Signed128 _Left, _Signed128 _Right) noexcept { + _NODISCARD friend constexpr _Signed128 operator%(_Signed128 _Left, _Signed128 _Right) noexcept { bool _Negative = false; _Left._Strip_negative(_Negative); @@ -1308,7 +1308,7 @@ struct _Signed128 : _Base128 { } _TEMPLATE_CLASS_INTEGRAL(_Ty) - _NODISCARD_FRIEND constexpr _Signed128 operator%(_Signed128 _Left, const _Ty _Right) noexcept { + _NODISCARD friend constexpr _Signed128 operator%(_Signed128 _Left, const _Ty _Right) noexcept { return _Left % _Signed128{_Right}; } @@ -1331,7 +1331,7 @@ struct _Signed128 : _Base128 { return _Left; } - _NODISCARD_FRIEND constexpr _Signed128 operator&(const _Signed128& _Left, const _Signed128& _Right) noexcept { + _NODISCARD friend constexpr _Signed128 operator&(const _Signed128& _Left, const _Signed128& _Right) noexcept { return _Signed128{_Left._Word[0] & _Right._Word[0], _Left._Word[1] & _Right._Word[1]}; } @@ -1341,7 +1341,7 @@ struct _Signed128 : _Base128 { return *this; } - _NODISCARD_FRIEND constexpr _Signed128 operator^(const _Signed128& _Left, const _Signed128& _Right) noexcept { + _NODISCARD friend constexpr _Signed128 operator^(const _Signed128& _Left, const _Signed128& _Right) noexcept { return _Signed128{_Left._Word[0] ^ _Right._Word[0], _Left._Word[1] ^ _Right._Word[1]}; } @@ -1351,7 +1351,7 @@ struct _Signed128 : _Base128 { return *this; } - _NODISCARD_FRIEND constexpr _Signed128 operator|(const _Signed128& _Left, const _Signed128& _Right) noexcept { + _NODISCARD friend constexpr _Signed128 operator|(const _Signed128& _Left, const _Signed128& _Right) noexcept { return _Signed128{_Left._Word[0] | _Right._Word[0], _Left._Word[1] | _Right._Word[1]}; } diff --git a/stl/inc/__msvc_ranges_to.hpp b/stl/inc/__msvc_ranges_to.hpp index bd4cfaea563..5477a7347e9 100644 --- a/stl/inc/__msvc_ranges_to.hpp +++ b/stl/inc/__msvc_ranges_to.hpp @@ -827,7 +827,7 @@ namespace ranges { return _STD invoke(*_Parent->_Fun, _Current[_Idx]); } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current == _Right._Current)) /* strengthened */ requires equality_comparable> { @@ -837,7 +837,7 @@ namespace ranges { return _Left._Current == _Right._Current; } - _NODISCARD_FRIEND constexpr bool operator<(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current < _Right._Current)) /* strengthened */ requires random_access_range<_Base> { @@ -846,25 +846,25 @@ namespace ranges { #endif // _ITERATOR_DEBUG_LEVEL != 0 return _Left._Current < _Right._Current; } - _NODISCARD_FRIEND constexpr bool operator>(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current < _Right._Current)) /* strengthened */ requires random_access_range<_Base> { return _Right < _Left; } - _NODISCARD_FRIEND constexpr bool operator<=(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<=(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current < _Right._Current)) /* strengthened */ requires random_access_range<_Base> { return !(_Right < _Left); } - _NODISCARD_FRIEND constexpr bool operator>=(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>=(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current < _Right._Current)) /* strengthened */ requires random_access_range<_Base> { return !(_Left < _Right); } - _NODISCARD_FRIEND constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current <=> _Right._Current)) /* strengthened */ requires random_access_range<_Base> && three_way_comparable> { @@ -874,7 +874,7 @@ namespace ranges { return _Left._Current <=> _Right._Current; } - _NODISCARD_FRIEND constexpr _Iterator operator+(_Iterator _It, const difference_type _Off) noexcept( + _NODISCARD friend constexpr _Iterator operator+(_Iterator _It, const difference_type _Off) noexcept( noexcept(_It._Current += _Off)) /* strengthened */ requires random_access_range<_Base> { @@ -884,7 +884,7 @@ namespace ranges { _It._Current += _Off; return _It; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const difference_type _Off, _Iterator _It) noexcept( + _NODISCARD friend constexpr _Iterator operator+(const difference_type _Off, _Iterator _It) noexcept( noexcept(_It._Current += _Off)) /* strengthened */ requires random_access_range<_Base> { @@ -895,7 +895,7 @@ namespace ranges { return _It; } - _NODISCARD_FRIEND constexpr _Iterator operator-(_Iterator _It, const difference_type _Off) noexcept( + _NODISCARD friend constexpr _Iterator operator-(_Iterator _It, const difference_type _Off) noexcept( noexcept(_It._Current -= _Off)) /* strengthened */ requires random_access_range<_Base> { @@ -907,7 +907,7 @@ namespace ranges { return _It; } - _NODISCARD_FRIEND constexpr difference_type operator-(const _Iterator& _Left, + _NODISCARD friend constexpr difference_type operator-(const _Iterator& _Left, const _Iterator& _Right) noexcept(noexcept(_Left._Current - _Right._Current)) /* strengthened */ requires sized_sentinel_for, iterator_t<_Base>> { @@ -958,14 +958,14 @@ namespace ranges { template requires sentinel_for, _Maybe_const_iter<_OtherConst>> - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator<_OtherConst>& _Left, + _NODISCARD friend constexpr bool operator==(const _Iterator<_OtherConst>& _Left, const _Sentinel& _Right) noexcept(noexcept(_Get_current(_Left) == _Right._Last)) /* strengthened */ { return _Get_current(_Left) == _Right._Last; } template requires sized_sentinel_for, _Maybe_const_iter<_OtherConst>> - _NODISCARD_FRIEND constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-( + _NODISCARD friend constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-( const _Iterator<_OtherConst>& _Left, const _Sentinel& _Right) noexcept(noexcept(_Get_current(_Left) - _Right._Last)) /* strengthened */ { return _Get_current(_Left) - _Right._Last; @@ -973,7 +973,7 @@ namespace ranges { template requires sized_sentinel_for, _Maybe_const_iter<_OtherConst>> - _NODISCARD_FRIEND constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> + _NODISCARD friend constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-(const _Sentinel& _Left, const _Iterator<_OtherConst>& _Right) noexcept( noexcept(_Left._Last - _Get_current(_Right))) /* strengthened */ { return _Left._Last - _Get_current(_Right); diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index 52daaedbaf5..5ef55aded17 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -990,7 +990,7 @@ class _String_view_iterator { return _Tmp; } - _NODISCARD_FRIEND constexpr _String_view_iterator operator+( + _NODISCARD friend constexpr _String_view_iterator operator+( const difference_type _Off, _String_view_iterator _Right) noexcept { _Right += _Off; return _Right; diff --git a/stl/inc/algorithm b/stl/inc/algorithm index 5510edb3d97..af08dfa626b 100644 --- a/stl/inc/algorithm +++ b/stl/inc/algorithm @@ -10274,7 +10274,7 @@ namespace ranges { auto _ULast = _RANGES _Uend(_Range); _STL_ASSERT( _UFirst != _ULast, "A range passed to std::ranges::minmax must not be empty. (N4971 [alg.min.max]/21)"); - if constexpr (forward_range<_Rng> && _Prefer_iterator_copies>) { + if constexpr (forward_range<_Rng> && _Prefer_iterator_copies) { return _Minmax_fwd_unchecked( _STD move(_UFirst), _STD move(_ULast), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); } else { diff --git a/stl/inc/array b/stl/inc/array index 6c9ee17926f..8f9b575f8ba 100644 --- a/stl/inc/array +++ b/stl/inc/array @@ -252,7 +252,7 @@ public: return _Tmp; } - _NODISCARD_FRIEND _CONSTEXPR17 _Array_const_iterator operator+( + _NODISCARD friend _CONSTEXPR17 _Array_const_iterator operator+( const ptrdiff_t _Off, _Array_const_iterator _Next) noexcept { _Next += _Off; return _Next; @@ -360,7 +360,7 @@ public: return _Tmp; } - _NODISCARD_FRIEND _CONSTEXPR17 _Array_iterator operator+(const ptrdiff_t _Off, _Array_iterator _Next) noexcept { + _NODISCARD friend _CONSTEXPR17 _Array_iterator operator+(const ptrdiff_t _Off, _Array_iterator _Next) noexcept { _Next += _Off; return _Next; } diff --git a/stl/inc/atomic b/stl/inc/atomic index 307168b01e2..69bb22d98a7 100644 --- a/stl/inc/atomic +++ b/stl/inc/atomic @@ -28,29 +28,10 @@ _STL_DISABLE_CLANG_WARNINGS #pragma push_macro("new") #undef new -#ifdef _WIN64 -#if _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 1 -#define _STD_COMPARE_EXCHANGE_128 _InterlockedCompareExchange128 -#else // ^^^ _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 1 / _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 0 vvv -// 16-byte atomics are separately compiled for x64, as not all x64 hardware has the cmpxchg16b -// instruction; in the event this instruction is not available, the fallback is a global -// synchronization object shared by all 16-byte atomics. -// (Note: machines without this instruction typically have 2 cores or fewer, so this isn't too bad) -// All pointer parameters must be 16-byte aligned. -extern "C" _NODISCARD unsigned char __stdcall __std_atomic_compare_exchange_128( - _Inout_bytecount_(16) long long* _Destination, _In_ long long _ExchangeHigh, _In_ long long _ExchangeLow, - _Inout_bytecount_(16) long long* _ComparandResult) noexcept; -extern "C" _NODISCARD char __stdcall __std_atomic_has_cmpxchg16b() noexcept; -#define _STD_COMPARE_EXCHANGE_128 __std_atomic_compare_exchange_128 -#endif // ^^^ _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 0 ^^^ -#endif // defined(_WIN64) - -// Controls whether atomic::is_always_lock_free triggers for sizeof(void *) or 2 * sizeof(void *) -#if _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 1 || !defined(_M_X64) || defined(_M_ARM64EC) -#define _ATOMIC_HAS_DCAS 1 -#else // ^^^ We always have DCAS / We only sometimes have DCAS vvv -#define _ATOMIC_HAS_DCAS 0 -#endif // ^^^ We only sometimes have DCAS ^^^ +// Allow _InterlockedCompareExchange128 to be used: +#if defined(__clang__) && defined(_M_X64) +#pragma clang attribute _STD_ATOMIC_HEADER.push([[gnu::target("cx16")]], apply_to = function) +#endif // ^^^ defined(__clang__) && defined(_M_X64) ^^^ // Controls whether ARM64 ldar/ldapr/stlr should be used #ifndef _STD_ATOMIC_USE_ARM64_LDAR_STLR @@ -603,7 +584,7 @@ inline bool __stdcall _Atomic_wait_compare_16_bytes(const void* _Storage, void* const auto _Cmp = static_cast(_Comparand); alignas(16) long long _Tmp[2] = {_Cmp[0], _Cmp[1]}; #if defined(_M_X64) && !defined(_M_ARM64EC) - return _STD_COMPARE_EXCHANGE_128(_Dest, _Tmp[1], _Tmp[0], _Tmp) != 0; + return _InterlockedCompareExchange128(_Dest, _Tmp[1], _Tmp[0], _Tmp) != 0; #else // ^^^ _M_X64 / ARM64, _M_ARM64EC vvv return _InterlockedCompareExchange128_nf(_Dest, _Tmp[1], _Tmp[0], _Tmp) != 0; #endif // ^^^ ARM64, _M_ARM64EC ^^^ @@ -1199,7 +1180,7 @@ struct _Atomic_storage<_Ty&, 16> { // lock-free using 16-byte intrinsics _NODISCARD _TVal load() const noexcept { // load with sequential consistency long long* const _Storage_ptr = const_cast(_STD _Atomic_address_as(_Storage)); _Int128 _Result{}; // atomic CAS 0 with 0 - (void) _STD_COMPARE_EXCHANGE_128(_Storage_ptr, 0, 0, &_Result._Low); + (void) _InterlockedCompareExchange128(_Storage_ptr, 0, 0, &_Result._Low); return reinterpret_cast<_TVal&>(_Result); } @@ -1270,7 +1251,7 @@ 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 = _STD_COMPARE_EXCHANGE_128(&reinterpret_cast(_Storage), _Desired_bytes._High, + _Result = _InterlockedCompareExchange128(&reinterpret_cast(_Storage), _Desired_bytes._High, _Desired_bytes._Low, &_Expected_temp._Low); #endif // ^^^ _M_X64 ^^^ if (_Result) { @@ -1296,7 +1277,7 @@ 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 = _STD_COMPARE_EXCHANGE_128( + _Result = _InterlockedCompareExchange128( &reinterpret_cast(_Storage), _Desired_bytes._High, _Desired_bytes._Low, &_Expected_temp._Low); #endif // ^^^ _M_X64 ^^^ if (_Result == 0) { @@ -1649,13 +1630,8 @@ struct _Atomic_integral<_Ty, 8> : _Atomic_storage<_Ty> { // atomic integral oper template constexpr bool _Is_always_lock_free = _TypeSize <= 8 && (_TypeSize & (_TypeSize - 1)) == 0; #else // ^^^ don't break ABI / break ABI vvv -#if _ATOMIC_HAS_DCAS template constexpr bool _Is_always_lock_free = _TypeSize <= 2 * sizeof(void*); -#else // ^^^ _ATOMIC_HAS_DCAS / !_ATOMIC_HAS_DCAS vvv -template -constexpr bool _Is_always_lock_free = _TypeSize <= sizeof(void*); -#endif // ^^^ !_ATOMIC_HAS_DCAS ^^^ #endif // ^^^ break ABI ^^^ template > @@ -2175,23 +2151,10 @@ public: static constexpr bool is_always_lock_free = _Is_always_lock_free; #endif // _HAS_CXX17 -#if 1 // TRANSITION, ABI _NODISCARD bool is_lock_free() const volatile noexcept { - constexpr bool _Result = sizeof(_Ty) <= 8 && (sizeof(_Ty) & sizeof(_Ty) - 1) == 0; - return _Result; + return _Is_always_lock_free; } -#else // ^^^ don't break ABI / break ABI vvv - - _NODISCARD bool is_lock_free() const volatile noexcept { -#if _ATOMIC_HAS_DCAS - return sizeof(_Ty) <= 2 * sizeof(void*); -#else // ^^^ _ATOMIC_HAS_DCAS / !_ATOMIC_HAS_DCAS vvv - return sizeof(_Ty) <= sizeof(void*) || (sizeof(_Ty) <= 2 * sizeof(void*) && __std_atomic_has_cmpxchg16b()); -#endif // ^^^ !_ATOMIC_HAS_DCAS ^^^ - } -#endif // ^^^ break ABI ^^^ - _NODISCARD bool is_lock_free() const noexcept { return static_cast(this)->is_lock_free(); } @@ -2341,7 +2304,7 @@ public: using value_type = _Ty; explicit atomic_ref(_Ty& _Value) noexcept /* strengthened */ : _Base(_Value) { - if constexpr (_Is_potentially_lock_free) { + if constexpr (is_always_lock_free) { _Check_alignment(_Value); } else { this->_Init_spinlock_for_ref(); @@ -2352,30 +2315,13 @@ public: atomic_ref& operator=(const atomic_ref&) = delete; - static constexpr bool _Is_potentially_lock_free = - sizeof(_Ty) <= 2 * sizeof(void*) && (sizeof(_Ty) & (sizeof(_Ty) - 1)) == 0; - static constexpr bool is_always_lock_free = -#if _ATOMIC_HAS_DCAS - _Is_potentially_lock_free; -#else // ^^^ _ATOMIC_HAS_DCAS / !_ATOMIC_HAS_DCAS vvv - _Is_potentially_lock_free && sizeof(_Ty) <= sizeof(void*); -#endif // ^^^ !_ATOMIC_HAS_DCAS ^^^ + sizeof(_Ty) <= 2 * sizeof(void*) && (sizeof(_Ty) & (sizeof(_Ty) - 1)) == 0; - static constexpr size_t required_alignment = _Is_potentially_lock_free ? sizeof(_Ty) : alignof(_Ty); + static constexpr size_t required_alignment = is_always_lock_free ? sizeof(_Ty) : alignof(_Ty); _NODISCARD bool is_lock_free() const noexcept { -#if _ATOMIC_HAS_DCAS return is_always_lock_free; -#else // ^^^ _ATOMIC_HAS_DCAS / !_ATOMIC_HAS_DCAS vvv - if constexpr (is_always_lock_free) { - return true; - } else if constexpr (_Is_potentially_lock_free) { - return __std_atomic_has_cmpxchg16b() != 0; - } else { - return false; - } -#endif // ^^^ !_ATOMIC_HAS_DCAS ^^^ } void store(const _Ty _Value) const noexcept { @@ -3049,16 +2995,18 @@ _STD_END #undef _ATOMIC_STORE_32_SEQ_CST #undef _ATOMIC_STORE_64_SEQ_CST #undef _ATOMIC_STORE_64_SEQ_CST_IX86 -#undef _ATOMIC_HAS_DCAS #undef _ATOMIC_STORE_SEQ_CST_ARM64 #undef __LOAD_ACQUIRE_ARM64 #undef _ATOMIC_LOAD_ARM64 #undef __STORE_RELEASE #undef _STD_ATOMIC_USE_ARM64_LDAR_STLR -#undef _STD_COMPARE_EXCHANGE_128 #undef _INVALID_MEMORY_ORDER +#if defined(__clang__) && defined(_M_X64) +#pragma clang attribute _STD_ATOMIC_HEADER.pop +#endif // ^^^ defined(__clang__) && defined(_M_X64) ^^^ + #pragma pop_macro("new") _STL_RESTORE_CLANG_WARNINGS #pragma warning(pop) diff --git a/stl/inc/bitset b/stl/inc/bitset index 66ec4c06c4b..f7eba3f7c7a 100644 --- a/stl/inc/bitset +++ b/stl/inc/bitset @@ -18,6 +18,10 @@ _STL_DISABLE_CLANG_WARNINGS #pragma push_macro("new") #undef new +#ifndef _STD_BITSET_TO_STREAM_STACK_RESERVATION +#define _STD_BITSET_TO_STREAM_STACK_RESERVATION 128 +#endif // !defined(_STD_BITSET_TO_STREAM_STACK_RESERVATION) + #if _USE_STD_VECTOR_ALGORITHMS extern "C" { __declspec(noalias) void __stdcall __std_bitset_to_string_1( @@ -357,26 +361,7 @@ public: // convert bitset to string basic_string<_Elem, _Tr, _Alloc> _Str; _Str._Resize_and_overwrite(_Bits, [this, _Elem0, _Elem1](_Elem* _Buf, size_t _Len) { -#if _USE_STD_VECTOR_ALGORITHMS - constexpr size_t _Bitset_vector_threshold = 32; - if constexpr (_Bits >= _Bitset_vector_threshold && is_integral_v<_Elem> && sizeof(_Elem) <= 2) { - if (!_Is_constant_evaluated()) { - if constexpr (sizeof(_Elem) == 1) { - __std_bitset_to_string_1(reinterpret_cast(_Buf), _Array, _Len, static_cast(_Elem0), - static_cast(_Elem1)); - } else { - _STL_INTERNAL_STATIC_ASSERT(sizeof(_Elem) == 2); - __std_bitset_to_string_2(reinterpret_cast(_Buf), _Array, _Len, - static_cast(_Elem0), static_cast(_Elem1)); - } - return _Len; - } - } -#endif // _USE_STD_VECTOR_ALGORITHMS - - for (size_t _Pos = 0; _Pos < _Len; ++_Pos) { - _Buf[_Pos] = _Subscript(_Len - 1 - _Pos) ? _Elem1 : _Elem0; - } + _To_string(_Buf, _Len, _Elem0, _Elem1); return _Len; }); return _Str; @@ -473,6 +458,32 @@ public: return _Array[_Wpos]; } + template + _CONSTEXPR23 void _To_string( + _Elem* const _Buf, const size_t _Len, const _Elem _Elem0, const _Elem _Elem1) const noexcept { +#if _USE_STD_VECTOR_ALGORITHMS + constexpr size_t _Bitset_vector_threshold = 32; + if constexpr (_Bits >= _Bitset_vector_threshold && is_integral_v<_Elem> && sizeof(_Elem) <= 2) { + if (!_Is_constant_evaluated()) { + if constexpr (sizeof(_Elem) == 1) { + __std_bitset_to_string_1(reinterpret_cast(_Buf), _Array, _Len, static_cast(_Elem0), + static_cast(_Elem1)); + } else { + _STL_INTERNAL_STATIC_ASSERT(sizeof(_Elem) == 2); + __std_bitset_to_string_2(reinterpret_cast(_Buf), _Array, _Len, + static_cast(_Elem0), static_cast(_Elem1)); + } + + return; + } + } +#endif // _USE_STD_VECTOR_ALGORITHMS + + for (size_t _Pos = 0; _Pos < _Len; ++_Pos) { + _Buf[_Pos] = _Subscript(_Len - 1 - _Pos) ? _Elem1 : _Elem0; + } + } + private: friend hash>; @@ -547,7 +558,14 @@ basic_ostream<_Elem, _Tr>& operator<<(basic_ostream<_Elem, _Tr>& _Ostr, const bi const _Elem _Elem0 = _Ctype_fac.widen('0'); const _Elem _Elem1 = _Ctype_fac.widen('1'); - return _Ostr << _Right.template to_string<_Elem, _Tr, allocator<_Elem>>(_Elem0, _Elem1); + if constexpr (_Bits * sizeof(_Elem) <= _STD_BITSET_TO_STREAM_STACK_RESERVATION) { + _Elem _Buf[_Bits + 1]; + _Right._To_string(_Buf, _Bits, _Elem0, _Elem1); + _Buf[_Bits] = _Elem{'\0'}; + return _Ostr << _Buf; + } else { + return _Ostr << _Right.template to_string<_Elem, _Tr, allocator<_Elem>>(_Elem0, _Elem1); + } } _EXPORT_STD template diff --git a/stl/inc/charconv b/stl/inc/charconv index 518841a249f..666be9f0372 100644 --- a/stl/inc/charconv +++ b/stl/inc/charconv @@ -208,7 +208,7 @@ _EXPORT_STD struct from_chars_result { const char* ptr; errc ec; #if _HAS_CXX20 - _NODISCARD_FRIEND bool operator==(const from_chars_result&, const from_chars_result&) = default; + _NODISCARD friend bool operator==(const from_chars_result&, const from_chars_result&) = default; #endif // _HAS_CXX20 }; diff --git a/stl/inc/compare b/stl/inc/compare index 38246ebb61c..adc7730731a 100644 --- a/stl/inc/compare +++ b/stl/inc/compare @@ -47,52 +47,52 @@ _EXPORT_STD struct partial_ordering { static const partial_ordering greater; static const partial_ordering unordered; - _NODISCARD_FRIEND constexpr bool operator==(const partial_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr bool operator==(const partial_ordering _Val, _Literal_zero) noexcept { return _Val._Value == 0; } - _NODISCARD_FRIEND constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default; + _NODISCARD friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default; - _NODISCARD_FRIEND constexpr bool operator<(const partial_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr bool operator<(const partial_ordering _Val, _Literal_zero) noexcept { return _Val._Value == static_cast<_Compare_t>(_Compare_ord::less); } - _NODISCARD_FRIEND constexpr bool operator>(const partial_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr bool operator>(const partial_ordering _Val, _Literal_zero) noexcept { return _Val._Value > 0; } - _NODISCARD_FRIEND constexpr bool operator<=(const partial_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr bool operator<=(const partial_ordering _Val, _Literal_zero) noexcept { // The stored value is either less (0xff), equivalent (0x00), greater (0x01), or unordered (0x80). // Subtracting from 0 produces either 0x01, 0x00, 0xff, or 0x80. The result is greater than or equal to 0 // if and only if the initial value was less or equivalent, for which we want to return true. return static_cast(0 - static_cast(_Val._Value)) >= 0; } - _NODISCARD_FRIEND constexpr bool operator>=(const partial_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr bool operator>=(const partial_ordering _Val, _Literal_zero) noexcept { return _Val._Value >= 0; } - _NODISCARD_FRIEND constexpr bool operator<(_Literal_zero, const partial_ordering _Val) noexcept { + _NODISCARD friend constexpr bool operator<(_Literal_zero, const partial_ordering _Val) noexcept { return _Val > 0; } - _NODISCARD_FRIEND constexpr bool operator>(_Literal_zero, const partial_ordering _Val) noexcept { + _NODISCARD friend constexpr bool operator>(_Literal_zero, const partial_ordering _Val) noexcept { return _Val < 0; } - _NODISCARD_FRIEND constexpr bool operator<=(_Literal_zero, const partial_ordering _Val) noexcept { + _NODISCARD friend constexpr bool operator<=(_Literal_zero, const partial_ordering _Val) noexcept { return _Val >= 0; } - _NODISCARD_FRIEND constexpr bool operator>=(_Literal_zero, const partial_ordering _Val) noexcept { + _NODISCARD friend constexpr bool operator>=(_Literal_zero, const partial_ordering _Val) noexcept { return _Val <= 0; } - _NODISCARD_FRIEND constexpr partial_ordering operator<=>(const partial_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr partial_ordering operator<=>(const partial_ordering _Val, _Literal_zero) noexcept { return _Val; } - _NODISCARD_FRIEND constexpr partial_ordering operator<=>(_Literal_zero, const partial_ordering _Val) noexcept { + _NODISCARD friend constexpr partial_ordering operator<=>(_Literal_zero, const partial_ordering _Val) noexcept { // The stored value is either less (0xff), equivalent (0x00), greater (0x01), or unordered (0x80). // Subtracting from 0 produces either 0x01, 0x00, 0xff, or 0x80. Note that the effect is to // exchange less for greater (and vice versa), while leaving equivalent and unordered unchanged. @@ -116,49 +116,49 @@ _EXPORT_STD struct weak_ordering { return {static_cast<_Compare_t>(_Value)}; } - _NODISCARD_FRIEND constexpr bool operator==(const weak_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr bool operator==(const weak_ordering _Val, _Literal_zero) noexcept { return _Val._Value == 0; } - _NODISCARD_FRIEND constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default; + _NODISCARD friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default; - _NODISCARD_FRIEND constexpr bool operator<(const weak_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr bool operator<(const weak_ordering _Val, _Literal_zero) noexcept { return _Val._Value < 0; } - _NODISCARD_FRIEND constexpr bool operator>(const weak_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr bool operator>(const weak_ordering _Val, _Literal_zero) noexcept { return _Val._Value > 0; } - _NODISCARD_FRIEND constexpr bool operator<=(const weak_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr bool operator<=(const weak_ordering _Val, _Literal_zero) noexcept { return _Val._Value <= 0; } - _NODISCARD_FRIEND constexpr bool operator>=(const weak_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr bool operator>=(const weak_ordering _Val, _Literal_zero) noexcept { return _Val._Value >= 0; } - _NODISCARD_FRIEND constexpr bool operator<(_Literal_zero, const weak_ordering _Val) noexcept { + _NODISCARD friend constexpr bool operator<(_Literal_zero, const weak_ordering _Val) noexcept { return _Val > 0; } - _NODISCARD_FRIEND constexpr bool operator>(_Literal_zero, const weak_ordering _Val) noexcept { + _NODISCARD friend constexpr bool operator>(_Literal_zero, const weak_ordering _Val) noexcept { return _Val < 0; } - _NODISCARD_FRIEND constexpr bool operator<=(_Literal_zero, const weak_ordering _Val) noexcept { + _NODISCARD friend constexpr bool operator<=(_Literal_zero, const weak_ordering _Val) noexcept { return _Val >= 0; } - _NODISCARD_FRIEND constexpr bool operator>=(_Literal_zero, const weak_ordering _Val) noexcept { + _NODISCARD friend constexpr bool operator>=(_Literal_zero, const weak_ordering _Val) noexcept { return _Val <= 0; } - _NODISCARD_FRIEND constexpr weak_ordering operator<=>(const weak_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr weak_ordering operator<=>(const weak_ordering _Val, _Literal_zero) noexcept { return _Val; } - _NODISCARD_FRIEND constexpr weak_ordering operator<=>(_Literal_zero, const weak_ordering _Val) noexcept { + _NODISCARD friend constexpr weak_ordering operator<=>(_Literal_zero, const weak_ordering _Val) noexcept { return {static_cast<_Compare_t>(-_Val._Value)}; } @@ -183,49 +183,49 @@ _EXPORT_STD struct strong_ordering { return {static_cast<_Compare_t>(_Value)}; } - _NODISCARD_FRIEND constexpr bool operator==(const strong_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr bool operator==(const strong_ordering _Val, _Literal_zero) noexcept { return _Val._Value == 0; } - _NODISCARD_FRIEND constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default; + _NODISCARD friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default; - _NODISCARD_FRIEND constexpr bool operator<(const strong_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr bool operator<(const strong_ordering _Val, _Literal_zero) noexcept { return _Val._Value < 0; } - _NODISCARD_FRIEND constexpr bool operator>(const strong_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr bool operator>(const strong_ordering _Val, _Literal_zero) noexcept { return _Val._Value > 0; } - _NODISCARD_FRIEND constexpr bool operator<=(const strong_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr bool operator<=(const strong_ordering _Val, _Literal_zero) noexcept { return _Val._Value <= 0; } - _NODISCARD_FRIEND constexpr bool operator>=(const strong_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr bool operator>=(const strong_ordering _Val, _Literal_zero) noexcept { return _Val._Value >= 0; } - _NODISCARD_FRIEND constexpr bool operator<(_Literal_zero, const strong_ordering _Val) noexcept { + _NODISCARD friend constexpr bool operator<(_Literal_zero, const strong_ordering _Val) noexcept { return _Val > 0; } - _NODISCARD_FRIEND constexpr bool operator>(_Literal_zero, const strong_ordering _Val) noexcept { + _NODISCARD friend constexpr bool operator>(_Literal_zero, const strong_ordering _Val) noexcept { return _Val < 0; } - _NODISCARD_FRIEND constexpr bool operator<=(_Literal_zero, const strong_ordering _Val) noexcept { + _NODISCARD friend constexpr bool operator<=(_Literal_zero, const strong_ordering _Val) noexcept { return _Val >= 0; } - _NODISCARD_FRIEND constexpr bool operator>=(_Literal_zero, const strong_ordering _Val) noexcept { + _NODISCARD friend constexpr bool operator>=(_Literal_zero, const strong_ordering _Val) noexcept { return _Val <= 0; } - _NODISCARD_FRIEND constexpr strong_ordering operator<=>(const strong_ordering _Val, _Literal_zero) noexcept { + _NODISCARD friend constexpr strong_ordering operator<=>(const strong_ordering _Val, _Literal_zero) noexcept { return _Val; } - _NODISCARD_FRIEND constexpr strong_ordering operator<=>(_Literal_zero, const strong_ordering _Val) noexcept { + _NODISCARD friend constexpr strong_ordering operator<=>(_Literal_zero, const strong_ordering _Val) noexcept { return {static_cast<_Compare_t>(-_Val._Value)}; } diff --git a/stl/inc/deque b/stl/inc/deque index 2756ad3a209..7c8ad1f9be5 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -82,7 +82,7 @@ public: return _Tmp; } - _NODISCARD_FRIEND _Deque_unchecked_const_iterator operator+( + _NODISCARD friend _Deque_unchecked_const_iterator operator+( const difference_type _Off, _Deque_unchecked_const_iterator _Next) noexcept { _Next += _Off; return _Next; @@ -202,7 +202,7 @@ public: return _Tmp; } - _NODISCARD_FRIEND _Deque_unchecked_iterator operator+( + _NODISCARD friend _Deque_unchecked_iterator operator+( const difference_type _Off, _Deque_unchecked_iterator _Next) noexcept { _Next += _Off; return _Next; @@ -323,7 +323,7 @@ public: return _Tmp; } - _NODISCARD_FRIEND _Deque_const_iterator operator+( + _NODISCARD friend _Deque_const_iterator operator+( const difference_type _Off, _Deque_const_iterator _Next) noexcept { _Next += _Off; return _Next; @@ -484,7 +484,7 @@ public: return _Tmp; } - _NODISCARD_FRIEND _Deque_iterator operator+(const difference_type _Off, _Deque_iterator _Next) noexcept { + _NODISCARD friend _Deque_iterator operator+(const difference_type _Off, _Deque_iterator _Next) noexcept { _Next += _Off; return _Next; } diff --git a/stl/inc/exception b/stl/inc/exception index 95721640b89..a5bee7ae569 100644 --- a/stl/inc/exception +++ b/stl/inc/exception @@ -269,28 +269,28 @@ public: __ExceptionPtrSwap(&_Lhs, &_Rhs); } - _NODISCARD_FRIEND bool operator==(const exception_ptr& _Lhs, const exception_ptr& _Rhs) noexcept { + _NODISCARD friend bool operator==(const exception_ptr& _Lhs, const exception_ptr& _Rhs) noexcept { return __ExceptionPtrCompare(&_Lhs, &_Rhs); } - _NODISCARD_FRIEND bool operator==(const exception_ptr& _Lhs, nullptr_t) noexcept { + _NODISCARD friend bool operator==(const exception_ptr& _Lhs, nullptr_t) noexcept { return !_Lhs; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator==(nullptr_t, const exception_ptr& _Rhs) noexcept { + _NODISCARD friend bool operator==(nullptr_t, const exception_ptr& _Rhs) noexcept { return !_Rhs; } - _NODISCARD_FRIEND bool operator!=(const exception_ptr& _Lhs, const exception_ptr& _Rhs) noexcept { + _NODISCARD friend bool operator!=(const exception_ptr& _Lhs, const exception_ptr& _Rhs) noexcept { return !(_Lhs == _Rhs); } - _NODISCARD_FRIEND bool operator!=(const exception_ptr& _Lhs, nullptr_t) noexcept { + _NODISCARD friend bool operator!=(const exception_ptr& _Lhs, nullptr_t) noexcept { return !(_Lhs == nullptr); } - _NODISCARD_FRIEND bool operator!=(nullptr_t, const exception_ptr& _Rhs) noexcept { + _NODISCARD friend bool operator!=(nullptr_t, const exception_ptr& _Rhs) noexcept { return !(nullptr == _Rhs); } #endif // !_HAS_CXX20 diff --git a/stl/inc/expected b/stl/inc/expected index a7016c7a296..aad81b7007e 100644 --- a/stl/inc/expected +++ b/stl/inc/expected @@ -87,18 +87,14 @@ public: } friend constexpr void swap(unexpected& _Left, unexpected& _Right) noexcept(is_nothrow_swappable_v<_Err>) -#if defined(__clang__) || defined(__EDG__) // TRANSITION, /permissive - requires is_swappable_v<_Err> -#else // ^^^ no workaround / workaround vvv - requires is_swappable<_Err>::value -#endif // ^^^ workaround ^^^ + requires is_swappable<_Err>::value // TRANSITION, /permissive needs ::value { _Left.swap(_Right); } // [expected.un.eq] template - _NODISCARD_FRIEND constexpr bool operator==(const unexpected& _Left, const unexpected<_UErr>& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const unexpected& _Left, const unexpected<_UErr>& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Left._Unexpected == _Right.error()))) /* strengthened */ { return _Left._Unexpected == _Right.error(); } @@ -612,11 +608,7 @@ public: friend constexpr void swap(expected& _Lhs, expected& _Rhs) noexcept( is_nothrow_move_constructible_v<_Ty> && is_nothrow_swappable_v<_Ty> && is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>) -#if defined(__clang__) || defined(__EDG__) // TRANSITION, /permissive - requires is_swappable_v<_Ty> && is_swappable_v<_Err> -#else // ^^^ no workaround / workaround vvv - requires is_swappable<_Ty>::value && is_swappable<_Err>::value -#endif // ^^^ workaround ^^^ + requires is_swappable<_Ty>::value && is_swappable<_Err>::value // TRANSITION, /permissive needs ::value && is_move_constructible_v<_Ty> && is_move_constructible_v<_Err> && (is_nothrow_move_constructible_v<_Ty> || is_nothrow_move_constructible_v<_Err>) { @@ -1140,7 +1132,7 @@ public: // [expected.object.eq] template requires (!is_void_v<_Uty>) - _NODISCARD_FRIEND constexpr bool operator==(const expected& _Left, const expected<_Uty, _UErr>& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const expected& _Left, const expected<_Uty, _UErr>& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Left._Value == *_Right)) && noexcept( _STD _Fake_copy_init(_Left._Unexpected == _Right.error()))) /* strengthened */ { if (_Left._Has_value != _Right.has_value()) { @@ -1153,7 +1145,7 @@ public: } template - _NODISCARD_FRIEND constexpr bool operator==(const expected& _Left, const _Uty& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const expected& _Left, const _Uty& _Right) noexcept( noexcept(static_cast(_Left._Value == _Right))) /* strengthened */ { if (_Left._Has_value) { return static_cast(_Left._Value == _Right); @@ -1163,7 +1155,7 @@ public: } template - _NODISCARD_FRIEND constexpr bool operator==(const expected& _Left, const unexpected<_UErr>& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const expected& _Left, const unexpected<_UErr>& _Right) noexcept( noexcept(static_cast(_Left._Unexpected == _Right.error()))) /* strengthened */ { if (_Left._Has_value) { return false; @@ -1876,7 +1868,7 @@ public: // [expected.void.eq] template requires is_void_v<_Uty> - _NODISCARD_FRIEND constexpr bool operator==(const expected& _Left, const expected<_Uty, _UErr>& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const expected& _Left, const expected<_Uty, _UErr>& _Right) noexcept( noexcept(static_cast(_Left._Unexpected == _Right.error()))) /* strengthened */ { if (_Left._Has_value != _Right.has_value()) { return false; @@ -1886,7 +1878,7 @@ public: } template - _NODISCARD_FRIEND constexpr bool operator==(const expected& _Left, const unexpected<_UErr>& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const expected& _Left, const unexpected<_UErr>& _Right) noexcept( noexcept(static_cast(_Left._Unexpected == _Right.error()))) /* strengthened */ { if (_Left._Has_value) { return false; diff --git a/stl/inc/filesystem b/stl/inc/filesystem index 2867eec5bb2..5c321608490 100644 --- a/stl/inc/filesystem +++ b/stl/inc/filesystem @@ -1346,37 +1346,37 @@ namespace filesystem { return _Istr; } - _NODISCARD_FRIEND bool operator==(const path& _Left, const path& _Right) noexcept { + _NODISCARD friend bool operator==(const path& _Left, const path& _Right) noexcept { return _Left.compare(_Right._Text) == 0; } #if _HAS_CXX20 - _NODISCARD_FRIEND strong_ordering operator<=>(const path& _Left, const path& _Right) noexcept { + _NODISCARD friend strong_ordering operator<=>(const path& _Left, const path& _Right) noexcept { return _Left.compare(_Right._Text) <=> 0; } #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv - _NODISCARD_FRIEND bool operator!=(const path& _Left, const path& _Right) noexcept { + _NODISCARD friend bool operator!=(const path& _Left, const path& _Right) noexcept { return _Left.compare(_Right) != 0; } - _NODISCARD_FRIEND bool operator<(const path& _Left, const path& _Right) noexcept { + _NODISCARD friend bool operator<(const path& _Left, const path& _Right) noexcept { return _Left.compare(_Right) < 0; } - _NODISCARD_FRIEND bool operator>(const path& _Left, const path& _Right) noexcept { + _NODISCARD friend bool operator>(const path& _Left, const path& _Right) noexcept { return _Left.compare(_Right) > 0; } - _NODISCARD_FRIEND bool operator<=(const path& _Left, const path& _Right) noexcept { + _NODISCARD friend bool operator<=(const path& _Left, const path& _Right) noexcept { return _Left.compare(_Right) <= 0; } - _NODISCARD_FRIEND bool operator>=(const path& _Left, const path& _Right) noexcept { + _NODISCARD friend bool operator>=(const path& _Left, const path& _Right) noexcept { return _Left.compare(_Right) >= 0; } #endif // ^^^ !_HAS_CXX20 ^^^ - _NODISCARD_FRIEND path operator/(const path& _Left, const path& _Right) { // append a pair of paths together + _NODISCARD friend path operator/(const path& _Left, const path& _Right) { // append a pair of paths together const auto _Right_size = _Right._Text.size(); const auto _Right_first = _Right._Text.data(); const auto _Right_last = _Right_first + _Right_size; @@ -1578,12 +1578,12 @@ namespace filesystem { return _Tmp; } - _NODISCARD_FRIEND bool operator==(const _Path_iterator& _Lhs, const _Path_iterator& _Rhs) { + _NODISCARD friend bool operator==(const _Path_iterator& _Lhs, const _Path_iterator& _Rhs) { return _Lhs._Position == _Rhs._Position; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const _Path_iterator& _Lhs, const _Path_iterator& _Rhs) { + _NODISCARD friend bool operator!=(const _Path_iterator& _Lhs, const _Path_iterator& _Rhs) { return _Lhs._Position != _Rhs._Position; } #endif // !_HAS_CXX20 @@ -1981,7 +1981,7 @@ namespace filesystem { } #if _HAS_CXX20 - _NODISCARD_FRIEND bool operator==(const file_status& _Lhs, const file_status& _Rhs) noexcept { + _NODISCARD friend bool operator==(const file_status& _Lhs, const file_status& _Rhs) noexcept { return _Lhs._Myftype == _Rhs._Myftype && _Lhs._Myperms == _Rhs._Myperms; } #endif // _HAS_CXX20 @@ -3719,7 +3719,7 @@ namespace filesystem { uintmax_t available; #if _HAS_CXX20 - _NODISCARD_FRIEND constexpr bool operator==(const space_info&, const space_info&) noexcept = default; + _NODISCARD friend constexpr bool operator==(const space_info&, const space_info&) noexcept = default; #endif // _HAS_CXX20 }; diff --git a/stl/inc/format b/stl/inc/format index 0dceebb0509..be7a99523d6 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -2079,8 +2079,6 @@ class _Format_arg_store<_Context> {}; _EXPORT_STD template class basic_format_args { public: - basic_format_args() noexcept = default; - basic_format_args(const _Format_arg_store<_Context>&) noexcept {} template @@ -2208,6 +2206,9 @@ private: _Out&& _OutputIt_, const basic_format_args& _Ctx_args, const _Lazy_locale& _Loc_) : _OutputIt(_STD move(_OutputIt_)), _Args(_Ctx_args), _Loc(_Loc_) {} + basic_format_context(const basic_format_context&) = delete; + basic_format_context& operator=(const basic_format_context&) = delete; + public: using iterator = _Out; using char_type = _CharT; diff --git a/stl/inc/functional b/stl/inc/functional index 5150939b5dd..5e81fc599f1 100644 --- a/stl/inc/functional +++ b/stl/inc/functional @@ -1946,7 +1946,7 @@ public: _Fn1._Swap(_Fn2); } - _NODISCARD_FRIEND bool operator==(const move_only_function& _This, nullptr_t) noexcept { + _NODISCARD friend bool operator==(const move_only_function& _This, nullptr_t) noexcept { return _This._Is_null(); } }; diff --git a/stl/inc/iosfwd b/stl/inc/iosfwd index 666c823a6ea..8e49430ac21 100644 --- a/stl/inc/iosfwd +++ b/stl/inc/iosfwd @@ -98,13 +98,13 @@ public: } template , int> = 0> - _NODISCARD_FRIEND bool operator==(const fpos& _Left, const _Int _Right) noexcept /* strengthened */ { + _NODISCARD friend bool operator==(const fpos& _Left, const _Int _Right) noexcept /* strengthened */ { return static_cast(_Left) == _Right; } #if !_HAS_CXX20 template , int> = 0> - _NODISCARD_FRIEND bool operator==(const _Int _Left, const fpos& _Right) noexcept /* strengthened */ { + _NODISCARD friend bool operator==(const _Int _Left, const fpos& _Right) noexcept /* strengthened */ { return _Left == static_cast(_Right); } @@ -113,12 +113,12 @@ public: } template , int> = 0> - _NODISCARD_FRIEND bool operator!=(const fpos& _Left, const _Int _Right) noexcept /* strengthened */ { + _NODISCARD friend bool operator!=(const fpos& _Left, const _Int _Right) noexcept /* strengthened */ { return static_cast(_Left) != _Right; } template , int> = 0> - _NODISCARD_FRIEND bool operator!=(const _Int _Left, const fpos& _Right) noexcept /* strengthened */ { + _NODISCARD friend bool operator!=(const _Int _Left, const fpos& _Right) noexcept /* strengthened */ { return _Left != static_cast(_Right); } #endif // !_HAS_CXX20 diff --git a/stl/inc/iterator b/stl/inc/iterator index 4fa118f4186..25ebe3b4345 100644 --- a/stl/inc/iterator +++ b/stl/inc/iterator @@ -285,7 +285,7 @@ public: } #if _HAS_CXX20 - _NODISCARD_FRIEND bool operator==(const istream_iterator& _Left, default_sentinel_t) noexcept /* strengthened */ { + _NODISCARD friend bool operator==(const istream_iterator& _Left, default_sentinel_t) noexcept /* strengthened */ { return !_Left._Myistr; } #endif // _HAS_CXX20 @@ -448,7 +448,7 @@ public: } #if _HAS_CXX20 - _NODISCARD_FRIEND bool operator==(const istreambuf_iterator& _Left, default_sentinel_t) { + _NODISCARD friend bool operator==(const istreambuf_iterator& _Left, default_sentinel_t) { if (!_Left._Got) { _Left._Peek(); } @@ -997,7 +997,7 @@ public: template _OSe> requires sentinel_for<_Se, _OIter> - _NODISCARD_FRIEND constexpr bool operator==( + _NODISCARD friend constexpr bool operator==( const common_iterator& _Left, const common_iterator<_OIter, _OSe>& _Right) { auto& _Right_val = _Right._Get_val(); #if _ITERATOR_DEBUG_LEVEL != 0 @@ -1027,7 +1027,7 @@ public: template _OIter, sized_sentinel_for<_Iter> _OSe> requires sized_sentinel_for<_Se, _OIter> - _NODISCARD_FRIEND constexpr iter_difference_t<_OIter> operator-( + _NODISCARD friend constexpr iter_difference_t<_OIter> operator-( const common_iterator& _Left, const common_iterator<_OIter, _OSe>& _Right) { auto& _Right_val = _Right._Get_val(); #if _ITERATOR_DEBUG_LEVEL != 0 @@ -1051,7 +1051,7 @@ public: } } - _NODISCARD_FRIEND constexpr decltype(auto) iter_move(const common_iterator& _Right) noexcept( + _NODISCARD friend constexpr decltype(auto) iter_move(const common_iterator& _Right) noexcept( noexcept(_RANGES iter_move(_Right._Val._Get_first()))) requires input_iterator<_Iter> { @@ -1288,7 +1288,7 @@ public: return counted_iterator{_Current + _Diff, static_cast>(_Length - _Diff)}; } - _NODISCARD_FRIEND constexpr counted_iterator operator+( + _NODISCARD friend constexpr counted_iterator operator+( const iter_difference_t<_Iter> _Diff, const counted_iterator& _Right) requires random_access_iterator<_Iter> { @@ -1313,7 +1313,7 @@ public: } template _Other> - _NODISCARD_FRIEND constexpr iter_difference_t<_Other> operator-( + _NODISCARD friend constexpr iter_difference_t<_Other> operator-( const counted_iterator& _Left, const counted_iterator<_Other>& _Right) noexcept /* strengthened */ { #if _ITERATOR_DEBUG_LEVEL != 0 _Same_sequence(_Left, _Right); @@ -1321,12 +1321,12 @@ public: return _Right.count() - _Left._Length; } - _NODISCARD_FRIEND constexpr iter_difference_t<_Iter> operator-( + _NODISCARD friend constexpr iter_difference_t<_Iter> operator-( const counted_iterator& _Left, default_sentinel_t) noexcept /* strengthened */ { return -_Left._Length; } - _NODISCARD_FRIEND constexpr iter_difference_t<_Iter> operator-( + _NODISCARD friend constexpr iter_difference_t<_Iter> operator-( default_sentinel_t, const counted_iterator& _Right) noexcept /* strengthened */ { return _Right._Length; } @@ -1344,7 +1344,7 @@ public: // [counted.iter.cmp] template _Other> - _NODISCARD_FRIEND constexpr bool operator==( + _NODISCARD friend constexpr bool operator==( const counted_iterator& _Left, const counted_iterator<_Other>& _Right) noexcept /* strengthened */ { #if _ITERATOR_DEBUG_LEVEL != 0 _Same_sequence(_Left, _Right); @@ -1352,13 +1352,13 @@ public: return _Left._Length == _Right.count(); } - _NODISCARD_FRIEND constexpr bool operator==(const counted_iterator& _Left, default_sentinel_t) noexcept + _NODISCARD friend constexpr bool operator==(const counted_iterator& _Left, default_sentinel_t) noexcept /* strengthened */ { return _Left._Length == 0; } template _Other> - _NODISCARD_FRIEND constexpr strong_ordering operator<=>( + _NODISCARD friend constexpr strong_ordering operator<=>( const counted_iterator& _Left, const counted_iterator<_Other>& _Right) noexcept /* strengthened */ { #if _ITERATOR_DEBUG_LEVEL != 0 _Same_sequence(_Left, _Right); @@ -1367,7 +1367,7 @@ public: } // [counted.iter.cust] - _NODISCARD_FRIEND constexpr decltype(auto) iter_move(const counted_iterator& _Right) noexcept( + _NODISCARD friend constexpr decltype(auto) iter_move(const counted_iterator& _Right) noexcept( noexcept(_RANGES iter_move(_Right._Current))) requires input_iterator<_Iter> { @@ -1585,7 +1585,7 @@ public: return _Tmp; } - _NODISCARD_FRIEND constexpr checked_array_iterator operator+( + _NODISCARD friend constexpr checked_array_iterator operator+( const difference_type _Off, const checked_array_iterator<_Ptr>& _Next) noexcept { return _Next + _Off; } @@ -1776,7 +1776,7 @@ public: return _Tmp; } - _NODISCARD_FRIEND constexpr unchecked_array_iterator operator+( + _NODISCARD friend constexpr unchecked_array_iterator operator+( const difference_type _Off, const unchecked_array_iterator& _Next) noexcept { return _Next + _Off; } diff --git a/stl/inc/mdspan b/stl/inc/mdspan index 3f5b9d3a117..2535e0d5cd3 100644 --- a/stl/inc/mdspan +++ b/stl/inc/mdspan @@ -253,7 +253,7 @@ public: : extents(span{_Exts}, make_index_sequence{}) {} template - _NODISCARD_FRIEND constexpr bool operator==( + _NODISCARD friend constexpr bool operator==( const extents& _Left, const extents<_OtherIndexType, _OtherExtents...>& _Right) noexcept { if constexpr (rank() != sizeof...(_OtherExtents)) { return false; @@ -603,7 +603,7 @@ public: template requires (extents_type::rank() == _OtherExtents::rank()) - _NODISCARD_FRIEND constexpr bool operator==(const mapping& _Left, const mapping<_OtherExtents>& _Right) noexcept { + _NODISCARD friend constexpr bool operator==(const mapping& _Left, const mapping<_OtherExtents>& _Right) noexcept { return _Left._Exts == _Right.extents(); } @@ -756,7 +756,7 @@ public: template requires (extents_type::rank() == _OtherExtents::rank()) - _NODISCARD_FRIEND constexpr bool operator==(const mapping& _Left, const mapping<_OtherExtents>& _Right) noexcept { + _NODISCARD friend constexpr bool operator==(const mapping& _Left, const mapping<_OtherExtents>& _Right) noexcept { return _Left._Exts == _Right.extents(); } @@ -986,7 +986,7 @@ public: template requires _Layout_mapping_alike<_OtherMapping> && (extents_type::rank() == _OtherMapping::extents_type::rank()) && (_OtherMapping::is_always_strided()) - _NODISCARD_FRIEND constexpr bool operator==(const mapping& _Left, const _OtherMapping& _Right) noexcept { + _NODISCARD friend constexpr bool operator==(const mapping& _Left, const _OtherMapping& _Right) noexcept { if constexpr (extents_type::rank() != 0) { if (_Left.extents() != _Right.extents()) { return false; diff --git a/stl/inc/numeric b/stl/inc/numeric index 34287fa0a97..528969fdc63 100644 --- a/stl/inc/numeric +++ b/stl/inc/numeric @@ -625,6 +625,19 @@ _NODISCARD constexpr common_type_t<_Mt, _Nt> gcd(const _Mt _Mx, const _Nt _Nx) n using _Common = common_type_t<_Mt, _Nt>; using _Common_unsigned = make_unsigned_t<_Common>; + if constexpr (is_signed_v<_Common>) { +#ifndef _DEBUG + if (_STD _Is_constant_evaluated()) +#endif // ^^^ !defined(_DEBUG) ^^^ + { + constexpr auto _Min_common = _STD _Min_limit<_Common>(); + if (_Mx == _Min_common || _Nx == _Min_common) { + _STL_REPORT_ERROR("Preconditions: |m| and |n| are representable as a value of common_type_t. " + "(N4981 [numeric.ops.gcd]/2, N4981 [numeric.ops.lcm]/2)"); + } + } + } + return _Select_countr_zero_impl<_Common_unsigned>([=](auto _Countr_zero_impl) { _Common_unsigned _Mx_magnitude = _Abs_u(_Mx); _Common_unsigned _Nx_magnitude = _Abs_u(_Nx); @@ -670,7 +683,21 @@ _NODISCARD constexpr common_type_t<_Mt, _Nt> lcm(const _Mt _Mx, const _Nt _Nx) n return 0; } - return static_cast<_Common>((_Mx_magnitude / _STD gcd(_Mx_magnitude, _Nx_magnitude)) * _Nx_magnitude); +#ifndef _DEBUG + if (!_STD _Is_constant_evaluated()) { + return static_cast<_Common>((_Mx_magnitude / _STD gcd(_Mx_magnitude, _Nx_magnitude)) * _Nx_magnitude); + } +#endif // ^^^ !defined(_DEBUG) ^^^ + + _Common_unsigned _Result = 0; + _Common_unsigned _Tmp = static_cast<_Common_unsigned>(_Mx_magnitude / _STD gcd(_Mx_magnitude, _Nx_magnitude)); + + if (_Mul_overflow(_Tmp, _Nx_magnitude, _Result) || !_In_range<_Common>(_Result)) { + _STL_REPORT_ERROR("Preconditions: The least common multiple of |m| and |n| is representable as a value of " + "type common_type_t. (N4981 [numeric.ops.lcm]/2)"); + } + + return static_cast<_Common>(_Result); } #endif // _HAS_CXX17 diff --git a/stl/inc/random b/stl/inc/random index 9fc33d3e15b..a429b7ab954 100644 --- a/stl/inc/random +++ b/stl/inc/random @@ -620,14 +620,14 @@ public: _Prev = _Temp; } - _NODISCARD_FRIEND bool operator==( + _NODISCARD friend bool operator==( const linear_congruential_engine& _Lhs, const linear_congruential_engine& _Rhs) noexcept /* strengthened */ { return _Lhs._Prev == _Rhs._Prev; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=( + _NODISCARD friend bool operator!=( const linear_congruential_engine& _Lhs, const linear_congruential_engine& _Rhs) noexcept /* strengthened */ { return _Lhs._Prev != _Rhs._Prev; @@ -711,13 +711,13 @@ public: _Prev = _Temp; } - _NODISCARD_FRIEND bool operator==(const linear_congruential& _Lhs, const linear_congruential& _Rhs) noexcept + _NODISCARD friend bool operator==(const linear_congruential& _Lhs, const linear_congruential& _Rhs) noexcept /* strengthened */ { return _Lhs._Prev == _Rhs._Prev; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const linear_congruential& _Lhs, const linear_congruential& _Rhs) noexcept + _NODISCARD friend bool operator!=(const linear_congruential& _Lhs, const linear_congruential& _Rhs) noexcept /* strengthened */ { return _Lhs._Prev != _Rhs._Prev; } @@ -864,12 +864,12 @@ public: } } - _NODISCARD_FRIEND bool operator==(const _Swc_base& _Left, const _Swc_base& _Right) noexcept /* strengthened */ { + _NODISCARD friend bool operator==(const _Swc_base& _Left, const _Swc_base& _Right) noexcept /* strengthened */ { return static_cast(_Left)._Equals(_Right) && _Left._Carry == _Right._Carry; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const _Swc_base& _Left, const _Swc_base& _Right) noexcept /* strengthened */ { + _NODISCARD friend bool operator!=(const _Swc_base& _Left, const _Swc_base& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } #endif // !_HAS_CXX20 @@ -1099,13 +1099,13 @@ public: return _Mx - 1; } - _NODISCARD_FRIEND bool operator==( + _NODISCARD friend bool operator==( const subtract_with_carry_engine& _Left, const subtract_with_carry_engine& _Right) noexcept /* strengthened */ { return static_cast(_Left) == static_cast(_Right); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=( + _NODISCARD friend bool operator!=( const subtract_with_carry_engine& _Left, const subtract_with_carry_engine& _Right) noexcept /* strengthened */ { return static_cast(_Left) != static_cast(_Right); } @@ -1298,13 +1298,13 @@ public: this->_Idx = _Nx; } - _NODISCARD_FRIEND bool operator==(const mersenne_twister& _Left, const mersenne_twister& _Right) noexcept + _NODISCARD friend bool operator==(const mersenne_twister& _Left, const mersenne_twister& _Right) noexcept /* strengthened */ { return _Left._Equals(_Right); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const mersenne_twister& _Left, const mersenne_twister& _Right) noexcept + _NODISCARD friend bool operator!=(const mersenne_twister& _Left, const mersenne_twister& _Right) noexcept /* strengthened */ { return !_Left._Equals(_Right); } @@ -1501,13 +1501,13 @@ public: return _Mybase::_WMSK; } - _NODISCARD_FRIEND bool operator==( + _NODISCARD friend bool operator==( const mersenne_twister_engine& _Left, const mersenne_twister_engine& _Right) noexcept /* strengthened */ { return static_cast(_Left) == static_cast(_Right); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=( + _NODISCARD friend bool operator!=( const mersenne_twister_engine& _Left, const mersenne_twister_engine& _Right) noexcept /* strengthened */ { return static_cast(_Left) != static_cast(_Right); } @@ -1604,12 +1604,12 @@ public: } } - _NODISCARD_FRIEND bool operator==(const discard_block& _Left, const discard_block& _Right) { + _NODISCARD friend bool operator==(const discard_block& _Left, const discard_block& _Right) { return _Left._Eng == _Right._Eng && _Left._Nx == _Right._Nx; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const discard_block& _Left, const discard_block& _Right) { + _NODISCARD friend bool operator!=(const discard_block& _Left, const discard_block& _Right) { return !(_Left == _Right); } #endif // !_HAS_CXX20 @@ -1685,12 +1685,12 @@ public: } } - _NODISCARD_FRIEND bool operator==(const _Discard_block_base& _Left, const _Discard_block_base& _Right) { + _NODISCARD friend bool operator==(const _Discard_block_base& _Left, const _Discard_block_base& _Right) { return _Left._Eng == _Right._Eng && _Left._Nx == _Right._Nx; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const _Discard_block_base& _Left, const _Discard_block_base& _Right) { + _NODISCARD friend bool operator!=(const _Discard_block_base& _Left, const _Discard_block_base& _Right) { return !(_Left == _Right); } #endif // !_HAS_CXX20 @@ -1771,12 +1771,12 @@ public: return (_Engine::max)(); } - _NODISCARD_FRIEND bool operator==(const discard_block_engine& _Left, const discard_block_engine& _Right) { + _NODISCARD friend bool operator==(const discard_block_engine& _Left, const discard_block_engine& _Right) { return static_cast(_Left) == static_cast(_Right); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const discard_block_engine& _Left, const discard_block_engine& _Right) { + _NODISCARD friend bool operator!=(const discard_block_engine& _Left, const discard_block_engine& _Right) { return static_cast(_Left) != static_cast(_Right); } #endif // !_HAS_CXX20 @@ -1886,12 +1886,12 @@ public: } } - _NODISCARD_FRIEND bool operator==(const independent_bits_engine& _Left, const independent_bits_engine& _Right) { + _NODISCARD friend bool operator==(const independent_bits_engine& _Left, const independent_bits_engine& _Right) { return _Left.base() == _Right.base(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const independent_bits_engine& _Left, const independent_bits_engine& _Right) { + _NODISCARD friend bool operator!=(const independent_bits_engine& _Left, const independent_bits_engine& _Right) { return !(_Left == _Right); } #endif // !_HAS_CXX20 @@ -2016,12 +2016,12 @@ public: } } - _NODISCARD_FRIEND bool operator==(const shuffle_order_engine& _Left, const shuffle_order_engine& _Right) { + _NODISCARD friend bool operator==(const shuffle_order_engine& _Left, const shuffle_order_engine& _Right) { return _Left.base() == _Right.base(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const shuffle_order_engine& _Left, const shuffle_order_engine& _Right) { + _NODISCARD friend bool operator!=(const shuffle_order_engine& _Left, const shuffle_order_engine& _Right) { return !(_Left == _Right); } #endif // !_HAS_CXX20 @@ -2205,13 +2205,13 @@ public: _Init(_Min0, _Max0); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return _Left._Min == _Right._Min && _Left._Max == _Right._Max; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -2413,13 +2413,13 @@ public: return _Ostr << static_cast(_Dist); } - _NODISCARD_FRIEND bool operator==( + _NODISCARD friend bool operator==( const uniform_int_distribution& _Left, const uniform_int_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=( + _NODISCARD friend bool operator!=( const uniform_int_distribution& _Left, const uniform_int_distribution& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -2442,13 +2442,13 @@ public: _Init(_Px0); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return _Left._Px == _Right._Px; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -2508,13 +2508,13 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==( + _NODISCARD friend bool operator==( const bernoulli_distribution& _Left, const bernoulli_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=( + _NODISCARD friend bool operator!=( const bernoulli_distribution& _Left, const bernoulli_distribution& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -2602,13 +2602,13 @@ public: _Init(_Px0); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return _Left._Px == _Right._Px; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -2669,13 +2669,13 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==( + _NODISCARD friend bool operator==( const geometric_distribution& _Left, const geometric_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=( + _NODISCARD friend bool operator!=( const geometric_distribution& _Left, const geometric_distribution& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -2758,13 +2758,13 @@ public: _Init(_Mean0); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return _Left._Mean == _Right._Mean; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -2832,13 +2832,13 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==(const poisson_distribution& _Left, const poisson_distribution& _Right) noexcept + _NODISCARD friend bool operator==(const poisson_distribution& _Left, const poisson_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const poisson_distribution& _Left, const poisson_distribution& _Right) noexcept + _NODISCARD friend bool operator!=(const poisson_distribution& _Left, const poisson_distribution& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -2913,13 +2913,13 @@ public: _Init(_Tx0, _Px0); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return _Left._Tx == _Right._Tx && _Left._Px == _Right._Px; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -3004,13 +3004,13 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==(const binomial_distribution& _Left, const binomial_distribution& _Right) noexcept + _NODISCARD friend bool operator==(const binomial_distribution& _Left, const binomial_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const binomial_distribution& _Left, const binomial_distribution& _Right) noexcept + _NODISCARD friend bool operator!=(const binomial_distribution& _Left, const binomial_distribution& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -3114,13 +3114,13 @@ public: _Init(_Min0, _Max0); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return _Left._Min == _Right._Min && _Left._Max == _Right._Max; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -3304,13 +3304,13 @@ public: return _Ostr << static_cast(_Dist); } - _NODISCARD_FRIEND bool operator==( + _NODISCARD friend bool operator==( const uniform_real_distribution& _Left, const uniform_real_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=( + _NODISCARD friend bool operator!=( const uniform_real_distribution& _Left, const uniform_real_distribution& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -3336,13 +3336,13 @@ public: _Init(_Lambda0); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return _Left._Lambda == _Right._Lambda; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -3401,13 +3401,13 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==( + _NODISCARD friend bool operator==( const exponential_distribution& _Left, const exponential_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=( + _NODISCARD friend bool operator!=( const exponential_distribution& _Left, const exponential_distribution& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -3456,13 +3456,13 @@ public: _Init(_Mean0, _Sigma0); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return _Left._Mean == _Right._Mean && _Left._Sigma == _Right._Sigma; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -3542,13 +3542,13 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==(const normal_distribution& _Left, const normal_distribution& _Right) noexcept + _NODISCARD friend bool operator==(const normal_distribution& _Left, const normal_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const normal_distribution& _Left, const normal_distribution& _Right) noexcept + _NODISCARD friend bool operator!=(const normal_distribution& _Left, const normal_distribution& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -3648,13 +3648,13 @@ public: _Init(_Alpha0, _Beta0); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return _Left._Alpha == _Right._Alpha && _Left._Beta == _Right._Beta; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -3729,13 +3729,13 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==(const gamma_distribution& _Left, const gamma_distribution& _Right) noexcept + _NODISCARD friend bool operator==(const gamma_distribution& _Left, const gamma_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const gamma_distribution& _Left, const gamma_distribution& _Right) noexcept + _NODISCARD friend bool operator!=(const gamma_distribution& _Left, const gamma_distribution& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -3842,13 +3842,13 @@ public: _Init(_Ax0, _Bx0); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return _Left._Ax == _Right._Ax && _Left._Bx == _Right._Bx; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -3918,13 +3918,13 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==(const weibull_distribution& _Left, const weibull_distribution& _Right) noexcept + _NODISCARD friend bool operator==(const weibull_distribution& _Left, const weibull_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const weibull_distribution& _Left, const weibull_distribution& _Right) noexcept + _NODISCARD friend bool operator!=(const weibull_distribution& _Left, const weibull_distribution& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -3977,13 +3977,13 @@ public: _Init(_Ax0, _Bx0); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return _Left._Ax == _Right._Ax && _Left._Bx == _Right._Bx; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -4052,13 +4052,13 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==( + _NODISCARD friend bool operator==( const extreme_value_distribution& _Left, const extreme_value_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=( + _NODISCARD friend bool operator!=( const extreme_value_distribution& _Left, const extreme_value_distribution& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -4111,13 +4111,13 @@ public: _Init(_Mx0, _Sx0); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return _Left._Mx == _Right._Mx && _Left._Sx == _Right._Sx; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -4186,13 +4186,13 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==( + _NODISCARD friend bool operator==( const lognormal_distribution& _Left, const lognormal_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=( + _NODISCARD friend bool operator!=( const lognormal_distribution& _Left, const lognormal_distribution& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -4245,13 +4245,13 @@ public: _Init(_Nx0); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return _Left._Nx == _Right._Nx; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -4310,13 +4310,13 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==( + _NODISCARD friend bool operator==( const chi_squared_distribution& _Left, const chi_squared_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=( + _NODISCARD friend bool operator!=( const chi_squared_distribution& _Left, const chi_squared_distribution& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -4365,13 +4365,13 @@ public: _Init(_Ax0, _Bx0); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return _Left._Ax == _Right._Ax && _Left._Bx == _Right._Bx; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -4440,13 +4440,13 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==(const cauchy_distribution& _Left, const cauchy_distribution& _Right) noexcept + _NODISCARD friend bool operator==(const cauchy_distribution& _Left, const cauchy_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const cauchy_distribution& _Left, const cauchy_distribution& _Right) noexcept + _NODISCARD friend bool operator!=(const cauchy_distribution& _Left, const cauchy_distribution& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -4558,13 +4558,13 @@ public: _Init(_Mx0, _Nx0); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return _Left._Mx == _Right._Mx && _Left._Nx == _Right._Nx; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -4634,13 +4634,13 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==(const fisher_f_distribution& _Left, const fisher_f_distribution& _Right) noexcept + _NODISCARD friend bool operator==(const fisher_f_distribution& _Left, const fisher_f_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const fisher_f_distribution& _Left, const fisher_f_distribution& _Right) noexcept + _NODISCARD friend bool operator!=(const fisher_f_distribution& _Left, const fisher_f_distribution& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -4704,13 +4704,13 @@ public: _Init(_Nx0); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return _Left._Nx == _Right._Nx; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -4769,13 +4769,13 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==( + _NODISCARD friend bool operator==( const student_t_distribution& _Left, const student_t_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=( + _NODISCARD friend bool operator!=( const student_t_distribution& _Left, const student_t_distribution& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -4839,13 +4839,13 @@ public: _Init(_Kx0, _Px0); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return _Left._Kx == _Right._Kx && _Left._Px == _Right._Px; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -4915,13 +4915,13 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==(const negative_binomial_distribution& _Left, + _NODISCARD friend bool operator==(const negative_binomial_distribution& _Left, const negative_binomial_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const negative_binomial_distribution& _Left, + _NODISCARD friend bool operator!=(const negative_binomial_distribution& _Left, const negative_binomial_distribution& _Right) noexcept /* strengthened */ { return !(_Left == _Right); } @@ -5004,12 +5004,12 @@ public: _Init(); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) { + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) { return _Left._Pvec == _Right._Pvec; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) { + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) { return !(_Left == _Right); } #endif // !_HAS_CXX20 @@ -5121,12 +5121,12 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==(const discrete_distribution& _Left, const discrete_distribution& _Right) { + _NODISCARD friend bool operator==(const discrete_distribution& _Left, const discrete_distribution& _Right) { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const discrete_distribution& _Left, const discrete_distribution& _Right) { + _NODISCARD friend bool operator!=(const discrete_distribution& _Left, const discrete_distribution& _Right) { return !(_Left == _Right); } #endif // !_HAS_CXX20 @@ -5213,13 +5213,13 @@ public: } } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) { + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) { return static_cast(_Left) == static_cast(_Right) && _Left._Bvec == _Right._Bvec; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) { + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) { return !(_Left == _Right); } #endif // !_HAS_CXX20 @@ -5297,13 +5297,13 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==( + _NODISCARD friend bool operator==( const piecewise_constant_distribution& _Left, const piecewise_constant_distribution& _Right) { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=( + _NODISCARD friend bool operator!=( const piecewise_constant_distribution& _Left, const piecewise_constant_distribution& _Right) { return !(_Left == _Right); } @@ -5410,13 +5410,13 @@ public: _Init(); } - _NODISCARD_FRIEND bool operator==(const param_type& _Left, const param_type& _Right) { + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) { return static_cast(_Left) == static_cast(_Right) && _Left._Bvec == _Right._Bvec; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const param_type& _Left, const param_type& _Right) { + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) { return !(_Left == _Right); } #endif // !_HAS_CXX20 @@ -5521,13 +5521,13 @@ public: return _Eval(_Eng, _Par0); } - _NODISCARD_FRIEND bool operator==( + _NODISCARD friend bool operator==( const piecewise_linear_distribution& _Left, const piecewise_linear_distribution& _Right) { return _Left.param() == _Right.param(); } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=( + _NODISCARD friend bool operator!=( const piecewise_linear_distribution& _Left, const piecewise_linear_distribution& _Right) { return !(_Left == _Right); } diff --git a/stl/inc/ranges b/stl/inc/ranges index 8129f9b14c6..db45abf8e13 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -813,46 +813,46 @@ namespace ranges { } } - _NODISCARD_FRIEND constexpr bool operator==(const _Ioterator& _Left, const _Ioterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const _Ioterator& _Left, const _Ioterator& _Right) noexcept( noexcept(_Left._Current == _Right._Current)) requires equality_comparable<_Wi> { return _Left._Current == _Right._Current; } - _NODISCARD_FRIEND constexpr bool operator<(const _Ioterator& _Left, const _Ioterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<(const _Ioterator& _Left, const _Ioterator& _Right) noexcept( noexcept(_Left._Current < _Right._Current)) /* strengthened */ requires totally_ordered<_Wi> { return _Left._Current < _Right._Current; } - _NODISCARD_FRIEND constexpr bool operator>(const _Ioterator& _Left, const _Ioterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>(const _Ioterator& _Left, const _Ioterator& _Right) noexcept( noexcept(_Right._Current < _Left._Current)) /* strengthened */ requires totally_ordered<_Wi> { return _Right._Current < _Left._Current; } - _NODISCARD_FRIEND constexpr bool operator<=(const _Ioterator& _Left, const _Ioterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<=(const _Ioterator& _Left, const _Ioterator& _Right) noexcept( noexcept(!(_Right._Current < _Left._Current))) /* strengthened */ requires totally_ordered<_Wi> { return !(_Right._Current < _Left._Current); } - _NODISCARD_FRIEND constexpr bool operator>=(const _Ioterator& _Left, const _Ioterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>=(const _Ioterator& _Left, const _Ioterator& _Right) noexcept( noexcept(!(_Left._Current < _Right._Current))) /* strengthened */ requires totally_ordered<_Wi> { return !(_Left._Current < _Right._Current); } - _NODISCARD_FRIEND constexpr auto operator<=>(const _Ioterator& _Left, const _Ioterator& _Right) noexcept( + _NODISCARD friend constexpr auto operator<=>(const _Ioterator& _Left, const _Ioterator& _Right) noexcept( noexcept(_Left._Current <=> _Right._Current)) requires totally_ordered<_Wi> && three_way_comparable<_Wi> { return _Left._Current <=> _Right._Current; } - _NODISCARD_FRIEND constexpr _Ioterator operator+(_Ioterator _It, const difference_type _Off) noexcept( + _NODISCARD friend constexpr _Ioterator operator+(_Ioterator _It, const difference_type _Off) noexcept( is_nothrow_move_constructible_v<_Ioterator> // && noexcept(_It += _Off)) /* strengthened */ requires _Advanceable<_Wi> @@ -860,7 +860,7 @@ namespace ranges { _It += _Off; return _It; } - _NODISCARD_FRIEND constexpr _Ioterator operator+(const difference_type _Off, _Ioterator _It) noexcept( + _NODISCARD friend constexpr _Ioterator operator+(const difference_type _Off, _Ioterator _It) noexcept( is_nothrow_move_constructible_v<_Wi> // && noexcept(static_cast<_Wi>(_It._Current + _Off))) /* strengthened */ requires _Advanceable<_Wi> @@ -868,7 +868,7 @@ namespace ranges { return _Ioterator{static_cast<_Wi>(_It._Current + _Off)}; } - _NODISCARD_FRIEND constexpr _Ioterator operator-(_Ioterator _It, const difference_type _Off) noexcept( + _NODISCARD friend constexpr _Ioterator operator-(_Ioterator _It, const difference_type _Off) noexcept( is_nothrow_move_constructible_v<_Ioterator> // && noexcept(_It -= _Off)) /* strengthened */ requires _Advanceable<_Wi> @@ -877,7 +877,7 @@ namespace ranges { return _It; } - _NODISCARD_FRIEND constexpr difference_type operator-(const _Ioterator& _Left, + _NODISCARD friend constexpr difference_type operator-(const _Ioterator& _Left, const _Ioterator& _Right) noexcept(noexcept(_Left._Current - _Right._Current)) /* strengthened */ requires _Advanceable<_Wi> { @@ -916,19 +916,19 @@ namespace ranges { public: /* [[no_unique_address]] */ _Bo _Last{}; - _NODISCARD_FRIEND constexpr bool operator==(const _It& _Left, const _Iotinel& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const _It& _Left, const _Iotinel& _Right) noexcept( noexcept(_Right._Equal(_Left))) /* strengthened */ { return _Right._Equal(_Left); } - _NODISCARD_FRIEND constexpr iter_difference_t<_Wi> operator-(const _It& _Left, const _Iotinel& _Right) noexcept( + _NODISCARD friend constexpr iter_difference_t<_Wi> operator-(const _It& _Left, const _Iotinel& _Right) noexcept( noexcept(_Right._Delta(_Left))) /* strengthened */ requires sized_sentinel_for<_Bo, _Wi> { return -_Right._Delta(_Left); } - _NODISCARD_FRIEND constexpr iter_difference_t<_Wi> operator-(const _Iotinel& _Left, const _It& _Right) noexcept( + _NODISCARD friend constexpr iter_difference_t<_Wi> operator-(const _Iotinel& _Left, const _It& _Right) noexcept( noexcept(_Left._Delta(_Right))) /* strengthened */ requires sized_sentinel_for<_Bo, _Wi> { @@ -1044,10 +1044,10 @@ namespace ranges { struct _Iota_fn { template _NODISCARD _STATIC_CALL_OPERATOR constexpr auto operator()(_Ty&& _Val) _CONST_CALL_OPERATOR - noexcept(noexcept(iota_view(static_cast<_Ty&&>(_Val)))) - requires requires { iota_view(static_cast<_Ty&&>(_Val)); } + noexcept(noexcept(iota_view>(static_cast<_Ty&&>(_Val)))) + requires requires { iota_view>(static_cast<_Ty&&>(_Val)); } { - return iota_view(static_cast<_Ty&&>(_Val)); + return iota_view>(static_cast<_Ty&&>(_Val)); } template @@ -1197,32 +1197,32 @@ namespace ranges { return *(*this + _Idx); } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept /* strengthened */ { return _Left._Current == _Right._Current; } - _NODISCARD_FRIEND constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) noexcept + _NODISCARD friend constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) noexcept /* strengthened */ { return _Left._Current <=> _Right._Current; } - _NODISCARD_FRIEND constexpr _Iterator operator+(_Iterator _Iter, difference_type _Off) noexcept + _NODISCARD friend constexpr _Iterator operator+(_Iterator _Iter, difference_type _Off) noexcept /* strengthened */ { _Iter += _Off; return _Iter; } - _NODISCARD_FRIEND constexpr _Iterator operator+(difference_type _Off, _Iterator _Iter) noexcept + _NODISCARD friend constexpr _Iterator operator+(difference_type _Off, _Iterator _Iter) noexcept /* strengthened */ { _Iter += _Off; return _Iter; } - _NODISCARD_FRIEND constexpr _Iterator operator-(_Iterator _Iter, difference_type _Off) noexcept + _NODISCARD friend constexpr _Iterator operator-(_Iterator _Iter, difference_type _Off) noexcept /* strengthened */ { _Iter -= _Off; return _Iter; } - _NODISCARD_FRIEND constexpr difference_type operator-( + _NODISCARD friend constexpr difference_type operator-( const _Iterator& _Left, const _Iterator& _Right) noexcept /* strengthened */ { return static_cast( static_cast(_Left._Current) - static_cast(_Right._Current)); @@ -1365,7 +1365,7 @@ namespace ranges { return _Parent->_Val; } - _NODISCARD_FRIEND bool operator==(const _Iterator& _Left, default_sentinel_t) noexcept /* strengthened */ { + _NODISCARD friend bool operator==(const _Iterator& _Left, default_sentinel_t) noexcept /* strengthened */ { return _Left._Parent->_Stream_at_end(); } }; @@ -1523,8 +1523,10 @@ namespace ranges { constexpr auto _Compile_time_max_size> = _Compile_time_max_size; namespace views { + // direct-non-list-initialization is specified in the Standard (N4981 [range.as.rvalue.overview]/2.2) + // and needed for EDG, DevCom-10698021 template - concept _Can_as_rvalue = requires(_Rng&& __r) { as_rvalue_view{static_cast<_Rng&&>(__r)}; }; + concept _Can_as_rvalue = requires(_Rng&& __r) { as_rvalue_view(static_cast<_Rng&&>(__r)); }; class _As_rvalue_fn : public _Pipe::_Base<_As_rvalue_fn> { private: @@ -1532,10 +1534,10 @@ namespace ranges { template _NODISCARD static consteval _Choice_t<_St> _Choose() noexcept { - if constexpr (same_as, range_reference_t<_Rng>>) { + if constexpr (input_range<_Rng> && same_as, range_reference_t<_Rng>>) { return {_St::_All, noexcept(views::all(_STD declval<_Rng>()))}; } else if constexpr (_Can_as_rvalue<_Rng>) { - return {_St::_As_rvalue, noexcept(as_rvalue_view{_STD declval<_Rng>()})}; + return {_St::_As_rvalue, noexcept(as_rvalue_view(_STD declval<_Rng>()))}; } else { return {_St::_None}; } @@ -1553,7 +1555,7 @@ namespace ranges { if constexpr (_Strat == _St::_All) { return views::all(_STD forward<_Rng>(_Range)); } else if constexpr (_Strat == _St::_As_rvalue) { - return as_rvalue_view{_STD forward<_Rng>(_Range)}; + return as_rvalue_view(_STD forward<_Rng>(_Range)); } else { _STL_INTERNAL_STATIC_ASSERT(false); // unexpected strategy } @@ -1686,7 +1688,7 @@ namespace ranges { return _Tmp; } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) requires equality_comparable> { #if _ITERATOR_DEBUG_LEVEL != 0 @@ -1696,7 +1698,7 @@ namespace ranges { return _Left._Current == _Right._Current; } - _NODISCARD_FRIEND constexpr range_rvalue_reference_t<_Vw> iter_move(const _Iterator& _It) noexcept( + _NODISCARD friend constexpr range_rvalue_reference_t<_Vw> iter_move(const _Iterator& _It) noexcept( noexcept(_RANGES iter_move(_It._Current))) { #if _ITERATOR_DEBUG_LEVEL != 0 _It._Check_dereference(); @@ -1737,7 +1739,7 @@ namespace ranges { return _Last; } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _It, const _Sentinel& _Se) noexcept( + _NODISCARD friend constexpr bool operator==(const _Iterator& _It, const _Sentinel& _Se) noexcept( noexcept(_It._Equal(_Se._Last))) /* strengthened */ { return _It._Equal(_Se._Last); } @@ -1870,13 +1872,13 @@ namespace ranges { return _Last; } - _NODISCARD_FRIEND constexpr bool operator==(const _Counted_iter<_Const>& _Left, const _Sentinel& _Right) { + _NODISCARD friend constexpr bool operator==(const _Counted_iter<_Const>& _Left, const _Sentinel& _Right) { return _Left.count() == 0 || _Left.base() == _Right._Last; } template requires sentinel_for<_Base_sentinel, _Base_iterator<_OtherConst>> - _NODISCARD_FRIEND constexpr bool operator==( + _NODISCARD friend constexpr bool operator==( const _Counted_iter<_OtherConst>& _Left, const _Sentinel& _Right) { return _Left.count() == 0 || _Left.base() == _Right._Last; } @@ -2167,13 +2169,13 @@ namespace ranges { return _Last; } - _NODISCARD_FRIEND constexpr bool operator==(const _Base_iterator& _Left, const _Sentinel& _Right) { + _NODISCARD friend constexpr bool operator==(const _Base_iterator& _Left, const _Sentinel& _Right) { return _Right._Last == _Left || !_STD invoke(*_Right._Pred, *_Left); } template requires sentinel_for<_Base_sentinel, _Maybe_const_iter<_OtherConst>> - _NODISCARD_FRIEND constexpr bool operator==( + _NODISCARD friend constexpr bool operator==( const _Maybe_const_iter<_OtherConst>& _Left, const _Sentinel& _Right) { return _Right._Last == _Left || !_STD invoke(*_Right._Pred, *_Left); } @@ -2882,7 +2884,7 @@ namespace ranges { return _Tmp; } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Outer == _Right._Outer && _Left._Inner == _Right._Inner)) /* strengthened */ requires _Deref_is_glvalue && forward_range<_Base> && equality_comparable<_InnerIter> { @@ -2892,7 +2894,7 @@ namespace ranges { return _Left._Outer == _Right._Outer && _Left._Inner == _Right._Inner; } - _NODISCARD_FRIEND constexpr decltype(auto) iter_move(const _Iterator& _It) noexcept( + _NODISCARD friend constexpr decltype(auto) iter_move(const _Iterator& _It) noexcept( noexcept(_RANGES iter_move(*_It._Inner))) { #if _ITERATOR_DEBUG_LEVEL != 0 _It._Check_dereference(); @@ -2946,7 +2948,7 @@ namespace ranges { template requires sentinel_for, _Maybe_const_iter<_OtherConst>> - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator<_OtherConst>& _Left, + _NODISCARD friend constexpr bool operator==(const _Iterator<_OtherConst>& _Left, const _Sentinel& _Right) noexcept(noexcept(_Right._Equal(_Left))) /* strengthened */ { return _Right._Equal(_Left); } @@ -3047,15 +3049,40 @@ namespace ranges { } // namespace views #if _HAS_CXX23 - template - concept _Compatible_joinable_ranges = - common_with, range_value_t<_Pat>> - && common_reference_with, range_reference_t<_Pat>> - && common_reference_with, range_rvalue_reference_t<_Pat>>; + template + using _Concat_reference_t = common_reference_t...>; + + template + using _Concat_value_t = common_type_t...>; + + template + using _Concat_rvalue_reference_t = common_reference_t...>; + + template + concept _Concat_indirectly_readable_impl = requires(const _It __i) { + { *__i } -> convertible_to<_Ref>; + { _RANGES iter_move(__i) } -> convertible_to<_RRef>; + }; + + template + concept _Concat_indirectly_readable = + common_reference_with<_Concat_reference_t<_Rngs...>&&, _Concat_value_t<_Rngs...>&> + && common_reference_with<_Concat_reference_t<_Rngs...>&&, _Concat_rvalue_reference_t<_Rngs...>&&> + && common_reference_with<_Concat_rvalue_reference_t<_Rngs...>&&, const _Concat_value_t<_Rngs...>&> + && (_Concat_indirectly_readable_impl<_Concat_reference_t<_Rngs...>, _Concat_rvalue_reference_t<_Rngs...>, + iterator_t<_Rngs>> + && ...); + + template + concept _Concatable = requires { + typename _Concat_reference_t<_Rngs...>; + typename _Concat_value_t<_Rngs...>; + typename _Concat_rvalue_reference_t<_Rngs...>; + } && _Concat_indirectly_readable<_Rngs...>; _EXPORT_STD template requires view<_Vw> && input_range> && view<_Pat> - && _Compatible_joinable_ranges, _Pat> + && _Concatable, _Pat> class join_with_view; template @@ -3089,7 +3116,7 @@ namespace ranges { _EXPORT_STD template requires view<_Vw> && input_range> && view<_Pat> - && _Compatible_joinable_ranges, _Pat> + && _Concatable, _Pat> class join_with_view : public _Join_with_view_outer_iter_base<_Vw, _Pat> { private: template @@ -3362,7 +3389,7 @@ namespace ranges { return _Tmp; } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) requires _Deref_is_glvalue && forward_range<_Base> && equality_comparable<_InnerIter> { if (_Left._Outer_it != _Right._Outer_it) { @@ -3385,7 +3412,7 @@ namespace ranges { _STL_UNREACHABLE; } - _NODISCARD_FRIEND constexpr decltype(auto) iter_move(const _Iterator& _It) { + _NODISCARD friend constexpr decltype(auto) iter_move(const _Iterator& _It) { using _Rvalue_ref = common_reference_t, iter_rvalue_reference_t<_PatternIter>>; return _It._Visit_inner_it<_Rvalue_ref>(_RANGES iter_move); @@ -3456,7 +3483,7 @@ namespace ranges { template requires sentinel_for, iterator_t<_Maybe_const<_OtherConst, _Vw>>> - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator<_OtherConst>& _Left, + _NODISCARD friend constexpr bool operator==(const _Iterator<_OtherConst>& _Left, const _Sentinel& _Right) noexcept(noexcept(_Right._Equal(_Left))) /* strengthened */ { return _Right._Equal(_Left); } @@ -3500,7 +3527,7 @@ namespace ranges { _NODISCARD constexpr auto begin() const requires forward_range && forward_range && is_reference_v<_InnerRng> - && input_range<_InnerRng> + && input_range<_InnerRng> && _Concatable, const _Pat> { return _Iterator{*this, _RANGES begin(_Range)}; } @@ -3517,7 +3544,7 @@ namespace ranges { _NODISCARD constexpr auto end() const requires forward_range && forward_range && is_reference_v<_InnerRng> - && input_range<_InnerRng> + && input_range<_InnerRng> && _Concatable, const _Pat> { if constexpr (forward_range<_InnerRng> && common_range<_Vw> && common_range<_InnerRng>) { return _Iterator{*this, _RANGES end(_Range)}; @@ -3756,13 +3783,13 @@ namespace ranges { } } - _NODISCARD_FRIEND constexpr bool operator==(const _Outer_iter& _Left, const _Outer_iter& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const _Outer_iter& _Left, const _Outer_iter& _Right) noexcept( noexcept(_Left._Current == _Right._Current)) /* strengthened */ requires forward_range<_BaseTy> { return _Left._Current == _Right._Current && _Left._Trailing_empty == _Right._Trailing_empty; } - _NODISCARD_FRIEND constexpr bool operator==(const _Outer_iter& _Left, default_sentinel_t) noexcept( + _NODISCARD friend constexpr bool operator==(const _Outer_iter& _Left, default_sentinel_t) noexcept( noexcept(_Left._At_end())) /* strengthened */ { return _Left._At_end() && !_Left._Trailing_empty; } @@ -3886,17 +3913,17 @@ namespace ranges { } } - _NODISCARD_FRIEND constexpr bool operator==(const _Inner_iter& _Left, const _Inner_iter& _Right) + _NODISCARD friend constexpr bool operator==(const _Inner_iter& _Left, const _Inner_iter& _Right) requires forward_range<_BaseTy> { return _Left._Equal(_Right); } - _NODISCARD_FRIEND constexpr bool operator==(const _Inner_iter& _Left, default_sentinel_t) { + _NODISCARD friend constexpr bool operator==(const _Inner_iter& _Left, default_sentinel_t) { return _Left._At_end(); } - _NODISCARD_FRIEND constexpr decltype(auto) iter_move(const _Inner_iter& _Iter) noexcept( + _NODISCARD friend constexpr decltype(auto) iter_move(const _Inner_iter& _Iter) noexcept( noexcept(_RANGES iter_move(_Iter._Get_current()))) { return _RANGES iter_move(_Iter._Get_current()); } @@ -4073,7 +4100,7 @@ namespace ranges { return _Tmp; } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current == _Right._Current)) /* strengthened */ { return _Left._Current == _Right._Current && _Left._Trailing_empty == _Right._Trailing_empty; } @@ -4095,7 +4122,7 @@ namespace ranges { && is_nothrow_move_constructible_v>) // strengthened : _Last(_RANGES end(_Parent._Range)) {} - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _It, const _Sentinel& _Se) noexcept( + _NODISCARD friend constexpr bool operator==(const _Iterator& _It, const _Sentinel& _Se) noexcept( noexcept(_Se._Equal(_It))) /* strengthened */ { return _Se._Equal(_It); } @@ -4845,46 +4872,46 @@ namespace ranges { return static_cast<_ElemTy>(_STD get<_Index>(*(_Current + _Idx))); } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current == _Right._Current)) /* strengthened */ requires equality_comparable> { return _Left._Current == _Right._Current; } - _NODISCARD_FRIEND constexpr bool operator<(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current < _Right._Current)) /* strengthened */ requires random_access_range<_Base> { return _Left._Current < _Right._Current; } - _NODISCARD_FRIEND constexpr bool operator>(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current < _Right._Current)) /* strengthened */ requires random_access_range<_Base> { return _Right < _Left; } - _NODISCARD_FRIEND constexpr bool operator<=(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<=(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current < _Right._Current)) /* strengthened */ requires random_access_range<_Base> { return !(_Right < _Left); } - _NODISCARD_FRIEND constexpr bool operator>=(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>=(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current < _Right._Current)) /* strengthened */ requires random_access_range<_Base> { return !(_Left < _Right); } - _NODISCARD_FRIEND constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current <=> _Right._Current)) /* strengthened */ requires random_access_range<_Base> && three_way_comparable> { return _Left._Current <=> _Right._Current; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const _Iterator& _It, const difference_type _Off) noexcept( + _NODISCARD friend constexpr _Iterator operator+(const _Iterator& _It, const difference_type _Off) noexcept( noexcept(_STD declval&>() += _Off) && is_nothrow_copy_constructible_v>) /* strengthened */ requires random_access_range<_Base> @@ -4897,7 +4924,7 @@ namespace ranges { return _Copy; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const difference_type _Off, const _Iterator& _It) noexcept( + _NODISCARD friend constexpr _Iterator operator+(const difference_type _Off, const _Iterator& _It) noexcept( noexcept(_STD declval&>() += _Off) && is_nothrow_copy_constructible_v>) /* strengthened */ requires random_access_range<_Base> @@ -4910,7 +4937,7 @@ namespace ranges { return _Copy; } - _NODISCARD_FRIEND constexpr _Iterator operator-(const _Iterator& _It, const difference_type _Off) noexcept( + _NODISCARD friend constexpr _Iterator operator-(const _Iterator& _It, const difference_type _Off) noexcept( noexcept(_STD declval&>() -= _Off) && is_nothrow_copy_constructible_v>) /* strengthened */ requires random_access_range<_Base> @@ -4924,7 +4951,7 @@ namespace ranges { return _Copy; } - _NODISCARD_FRIEND constexpr difference_type operator-(const _Iterator& _Left, + _NODISCARD friend constexpr difference_type operator-(const _Iterator& _Left, const _Iterator& _Right) noexcept(noexcept(_Left._Current - _Right._Current)) /* strengthened */ requires sized_sentinel_for, iterator_t<_Base>> { @@ -4967,14 +4994,14 @@ namespace ranges { template requires sentinel_for, _Maybe_const_iter<_OtherConst>> - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator<_OtherConst>& _Left, + _NODISCARD friend constexpr bool operator==(const _Iterator<_OtherConst>& _Left, const _Sentinel& _Right) noexcept(noexcept(_Get_current(_Left) == _Right._Last)) /* strengthened */ { return _Get_current(_Left) == _Right._Last; } template requires sized_sentinel_for, _Maybe_const_iter<_OtherConst>> - _NODISCARD_FRIEND constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-( + _NODISCARD friend constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-( const _Iterator<_OtherConst>& _Left, const _Sentinel& _Right) noexcept(noexcept(_Get_current(_Left) - _Right._Last)) /* strengthened */ { return _Get_current(_Left) - _Right._Last; @@ -4982,7 +5009,7 @@ namespace ranges { template requires sized_sentinel_for, _Maybe_const_iter<_OtherConst>> - _NODISCARD_FRIEND constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> + _NODISCARD friend constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-(const _Sentinel& _Left, const _Iterator<_OtherConst>& _Right) noexcept( noexcept(_Left._Last - _Get_current(_Right))) /* strengthened */ { return _Left._Last - _Get_current(_Right); @@ -5214,16 +5241,16 @@ namespace ranges { return _Reference_type{static_cast(_Pos + _Off), _Current[_Off]}; } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept { + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept { return _Left._Pos == _Right._Pos; } - _NODISCARD_FRIEND constexpr strong_ordering operator<=>( + _NODISCARD friend constexpr strong_ordering operator<=>( const _Iterator& _Left, const _Iterator& _Right) noexcept { return _Left._Pos <=> _Right._Pos; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const _Iterator& _It, const difference_type _Off) noexcept( + _NODISCARD friend constexpr _Iterator operator+(const _Iterator& _It, const difference_type _Off) noexcept( is_nothrow_copy_constructible_v<_Iterator> // && noexcept(_STD declval<_Iterator&>() += _Off)) // strengthened requires random_access_range<_Base_t> @@ -5233,14 +5260,14 @@ namespace ranges { return _Tmp; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const difference_type _Off, const _Iterator& _It) noexcept( + _NODISCARD friend constexpr _Iterator operator+(const difference_type _Off, const _Iterator& _It) noexcept( noexcept(_It + _Off)) // strengthened requires random_access_range<_Base_t> { return _It + _Off; } - _NODISCARD_FRIEND constexpr _Iterator operator-(const _Iterator& _It, const difference_type _Off) noexcept( + _NODISCARD friend constexpr _Iterator operator-(const _Iterator& _It, const difference_type _Off) noexcept( is_nothrow_copy_constructible_v<_Iterator> // && noexcept(_STD declval<_Iterator&>() -= _Off)) // strengthened requires random_access_range<_Base_t> @@ -5250,12 +5277,12 @@ namespace ranges { return _Tmp; } - _NODISCARD_FRIEND constexpr difference_type operator-( + _NODISCARD friend constexpr difference_type operator-( const _Iterator& _Left, const _Iterator& _Right) noexcept { return _Left._Pos - _Right._Pos; } - _NODISCARD_FRIEND constexpr auto iter_move(const _Iterator& _It) noexcept( + _NODISCARD friend constexpr auto iter_move(const _Iterator& _It) noexcept( noexcept(_RANGES iter_move(_It._Current)) && is_nothrow_move_constructible_v>) { return tuple>{ @@ -5306,14 +5333,14 @@ namespace ranges { template requires sentinel_for<_Base_sentinel, iterator_t<_Maybe_const<_OtherConst, _Vw>>> - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator<_OtherConst>& _It, + _NODISCARD friend constexpr bool operator==(const _Iterator<_OtherConst>& _It, const _Sentinel& _Se) noexcept(noexcept(_Se._Equal(_It))) /* strengthened */ { return _Se._Equal(_It); } template requires sized_sentinel_for<_Base_sentinel, iterator_t<_Maybe_const<_OtherConst, _Vw>>> - _NODISCARD_FRIEND constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-( + _NODISCARD friend constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-( const _Iterator<_OtherConst>& _It, const _Sentinel& _Se) // noexcept(noexcept(_Se._Distance_from(_It))) /* strengthened */ { return -_Se._Distance_from(_It); @@ -5321,7 +5348,7 @@ namespace ranges { template requires sized_sentinel_for<_Base_sentinel, iterator_t<_Maybe_const<_OtherConst, _Vw>>> - _NODISCARD_FRIEND constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-( + _NODISCARD friend constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-( const _Sentinel& _Se, const _Iterator<_OtherConst>& _It) // noexcept(noexcept(_Se._Distance_from(_It))) /* strengthened */ { return _Se._Distance_from(_It); @@ -5516,26 +5543,26 @@ namespace ranges { } } - _NODISCARD_FRIEND constexpr bool operator==(const _Inner_iterator& _Left, default_sentinel_t) noexcept + _NODISCARD friend constexpr bool operator==(const _Inner_iterator& _Left, default_sentinel_t) noexcept /* strengthened */ { return _Left._Get_remainder() == 0; } - _NODISCARD_FRIEND constexpr difference_type operator-(default_sentinel_t, + _NODISCARD friend constexpr difference_type operator-(default_sentinel_t, const _Inner_iterator& _Right) noexcept(noexcept(_Right._Get_size())) /* strengthened */ requires sized_sentinel_for, iterator_t<_Vw>> { return _Right._Get_size(); } - _NODISCARD_FRIEND constexpr difference_type operator-(const _Inner_iterator& _Left, + _NODISCARD friend constexpr difference_type operator-(const _Inner_iterator& _Left, default_sentinel_t) noexcept(noexcept(_Left._Get_size())) /* strengthened */ requires sized_sentinel_for, iterator_t<_Vw>> { return -_Left._Get_size(); } - _NODISCARD_FRIEND constexpr range_rvalue_reference_t<_Vw> iter_move(const _Inner_iterator& _It) noexcept( + _NODISCARD friend constexpr range_rvalue_reference_t<_Vw> iter_move(const _Inner_iterator& _It) noexcept( noexcept(_RANGES iter_move(_It._Get_current()))) { return _RANGES iter_move(_It._Get_current()); } @@ -5625,19 +5652,19 @@ namespace ranges { _Parent->_Remainder = _Parent->_Count; } - _NODISCARD_FRIEND constexpr bool operator==(const _Outer_iterator& _Left, default_sentinel_t) noexcept( + _NODISCARD friend constexpr bool operator==(const _Outer_iterator& _Left, default_sentinel_t) noexcept( noexcept(_Left._Is_end())) /* strengthened */ { return _Left._Is_end(); } - _NODISCARD_FRIEND constexpr difference_type operator-(default_sentinel_t, + _NODISCARD friend constexpr difference_type operator-(default_sentinel_t, const _Outer_iterator& _Right) noexcept(noexcept(_Right._Get_size())) /* strengthened */ requires sized_sentinel_for, iterator_t<_Vw>> { return _Right._Get_size(); } - _NODISCARD_FRIEND constexpr difference_type operator-(const _Outer_iterator& _Left, + _NODISCARD friend constexpr difference_type operator-(const _Outer_iterator& _Left, default_sentinel_t) noexcept(noexcept(_Left._Get_size())) /* strengthened */ requires sized_sentinel_for, iterator_t<_Vw>> { @@ -5821,52 +5848,52 @@ namespace ranges { return *(*this + _Off); } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Left._Current == _Right._Current))) /* strengthened */ { return _Left._Current == _Right._Current; } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, default_sentinel_t) noexcept( + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, default_sentinel_t) noexcept( noexcept(_STD _Fake_copy_init(_Left._Current == _Left._End))) /* strengthened */ { return _Left._Current == _Left._End; } - _NODISCARD_FRIEND constexpr bool operator<(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Left._Current < _Right._Current))) /* strengthened */ requires random_access_range<_Base> { return _Left._Current < _Right._Current; } - _NODISCARD_FRIEND constexpr bool operator>(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Right._Current < _Left._Current))) /* strengthened */ requires random_access_range<_Base> { return _Right._Current < _Left._Current; } - _NODISCARD_FRIEND constexpr bool operator<=(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<=(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(!(_Right._Current < _Left._Current)))) /* strengthened */ requires random_access_range<_Base> { return !(_Right._Current < _Left._Current); } - _NODISCARD_FRIEND constexpr bool operator>=(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>=(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(!(_Left._Current < _Right._Current)))) /* strengthened */ requires random_access_range<_Base> { return !(_Left._Current < _Right._Current); } - _NODISCARD_FRIEND constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current <=> _Right._Current)) /* strengthened */ requires random_access_range<_Base> && three_way_comparable<_Base_iterator> { return _Left._Current <=> _Right._Current; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const _Iterator& _It, const difference_type _Off) noexcept( + _NODISCARD friend constexpr _Iterator operator+(const _Iterator& _It, const difference_type _Off) noexcept( is_nothrow_copy_constructible_v<_Iterator> // && noexcept(_STD declval<_Iterator&>() += _Off)) /* strengthened */ requires random_access_range<_Base> @@ -5876,7 +5903,7 @@ namespace ranges { return _Copy; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const difference_type _Off, const _Iterator& _It) noexcept( + _NODISCARD friend constexpr _Iterator operator+(const difference_type _Off, const _Iterator& _It) noexcept( is_nothrow_copy_constructible_v<_Iterator> // && noexcept(_STD declval<_Iterator&>() += _Off)) /* strengthened */ requires random_access_range<_Base> @@ -5886,7 +5913,7 @@ namespace ranges { return _Copy; } - _NODISCARD_FRIEND constexpr _Iterator operator-(const _Iterator& _It, const difference_type _Off) noexcept( + _NODISCARD friend constexpr _Iterator operator-(const _Iterator& _It, const difference_type _Off) noexcept( is_nothrow_copy_constructible_v<_Iterator> // && noexcept(_STD declval<_Iterator&>() -= _Off)) /* strengthened */ requires random_access_range<_Base> @@ -5896,21 +5923,21 @@ namespace ranges { return _Copy; } - _NODISCARD_FRIEND constexpr difference_type operator-(const _Iterator& _Left, + _NODISCARD friend constexpr difference_type operator-(const _Iterator& _Left, const _Iterator& _Right) noexcept(noexcept(_Left._Current - _Right._Current)) /* strengthened */ requires sized_sentinel_for<_Base_iterator, _Base_iterator> { return (_Left._Current - _Right._Current + _Left._Missing - _Right._Missing) / _Left._Count; } - _NODISCARD_FRIEND constexpr difference_type operator-(default_sentinel_t, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr difference_type operator-(default_sentinel_t, const _Iterator& _Right) noexcept( noexcept(_Right._End - _Right._Current)) /* strengthened */ requires sized_sentinel_for<_Base_sentinel, _Base_iterator> { return _Div_ceil(_Right._End - _Right._Current, _Right._Count); } - _NODISCARD_FRIEND constexpr difference_type operator-(const _Iterator& _Left, default_sentinel_t) noexcept( + _NODISCARD friend constexpr difference_type operator-(const _Iterator& _Left, default_sentinel_t) noexcept( noexcept(_Left._End - _Left._Current)) /* strengthened */ requires sized_sentinel_for<_Base_sentinel, _Base_iterator> { @@ -6178,7 +6205,7 @@ namespace ranges { return views::counted(_Current + _Off, _Count); } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Left._Current == _Right._Current))) /* strengthened */ { if constexpr (_Slide_caches_first<_Base>) { return _Left._Last_element == _Right._Last_element; @@ -6187,42 +6214,42 @@ namespace ranges { } } - _NODISCARD_FRIEND constexpr bool operator<(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Left._Current < _Right._Current))) /* strengthened */ requires random_access_range<_Base> { return _Left._Current < _Right._Current; } - _NODISCARD_FRIEND constexpr bool operator>(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Right._Current < _Left._Current))) /* strengthened */ requires random_access_range<_Base> { return _Right._Current < _Left._Current; } - _NODISCARD_FRIEND constexpr bool operator<=(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<=(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(!(_Right._Current < _Left._Current)))) /* strengthened */ requires random_access_range<_Base> { return !(_Right._Current < _Left._Current); } - _NODISCARD_FRIEND constexpr bool operator>=(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>=(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(!(_Left._Current < _Right._Current)))) /* strengthened */ requires random_access_range<_Base> { return !(_Left._Current < _Right._Current); } - _NODISCARD_FRIEND constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current <=> _Right._Current)) /* strengthened */ requires random_access_range<_Base> && three_way_comparable<_Base_iterator> { return _Left._Current <=> _Right._Current; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const _Iterator& _It, const difference_type _Off) noexcept( + _NODISCARD friend constexpr _Iterator operator+(const _Iterator& _It, const difference_type _Off) noexcept( noexcept(_STD declval<_Iterator&>() += _Off)) /* strengthened */ requires random_access_range<_Base> { @@ -6231,7 +6258,7 @@ namespace ranges { return _Copy; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const difference_type _Off, const _Iterator& _It) noexcept( + _NODISCARD friend constexpr _Iterator operator+(const difference_type _Off, const _Iterator& _It) noexcept( noexcept(_STD declval<_Iterator&>() += _Off)) /* strengthened */ requires random_access_range<_Base> { @@ -6240,7 +6267,7 @@ namespace ranges { return _Copy; } - _NODISCARD_FRIEND constexpr _Iterator operator-(const _Iterator& _It, const difference_type _Off) noexcept( + _NODISCARD friend constexpr _Iterator operator-(const _Iterator& _It, const difference_type _Off) noexcept( noexcept(_STD declval<_Iterator&>() -= _Off)) /* strengthened */ requires random_access_range<_Base> { @@ -6249,7 +6276,7 @@ namespace ranges { return _Copy; } - _NODISCARD_FRIEND constexpr difference_type operator-(const _Iterator& _Left, + _NODISCARD friend constexpr difference_type operator-(const _Iterator& _Left, const _Iterator& _Right) noexcept(noexcept(_Left._Current - _Right._Current)) /* strengthened */ requires sized_sentinel_for<_Base_iterator, _Base_iterator> { @@ -6273,20 +6300,20 @@ namespace ranges { public: _Sentinel() = default; - _NODISCARD_FRIEND constexpr bool + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, const _Sentinel& _Right) noexcept(noexcept( _STD _Fake_copy_init(_Left._Get_last_element() == _Right._Last))) /* strengthened */ { return _Left._Get_last_element() == _Right._Last; } - _NODISCARD_FRIEND constexpr range_difference_t<_Vw> operator-(const _Iterator& _Left, + _NODISCARD friend constexpr range_difference_t<_Vw> operator-(const _Iterator& _Left, const _Sentinel& _Right) noexcept(noexcept(_Left._Get_last_element() - _Right._Last)) /* strengthened */ requires sized_sentinel_for, iterator_t<_Vw>> { return _Left._Get_last_element() - _Right._Last; } - _NODISCARD_FRIEND constexpr range_difference_t<_Vw> + _NODISCARD friend constexpr range_difference_t<_Vw> operator-(const _Sentinel& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Last - _Right._Get_last_element())) /* strengthened */ requires sized_sentinel_for, iterator_t<_Vw>> @@ -6524,12 +6551,12 @@ namespace ranges { return _Tmp; } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Left._Current == _Right._Current))) /* strengthened */ { return _Left._Current == _Right._Current; } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, default_sentinel_t) noexcept( + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, default_sentinel_t) noexcept( noexcept(_STD _Fake_copy_init(_Left._Current == _Left._Next))) /* strengthened */ { return _Left._Current == _Left._Next; } @@ -6789,54 +6816,54 @@ namespace ranges { return *(*this + _Off); } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _It, default_sentinel_t) noexcept( + _NODISCARD friend constexpr bool operator==(const _Iterator& _It, default_sentinel_t) noexcept( noexcept(_STD _Fake_copy_init(_It._Current == _It._End))) /* strengthened */ { return _It._Current == _It._End; } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Left._Current == _Right._Current))) // strengthened requires equality_comparable<_Base_iterator> { return _Left._Current == _Right._Current; } - _NODISCARD_FRIEND constexpr bool operator<(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Left._Current < _Right._Current))) // strengthened requires random_access_range<_Base> { return _Left._Current < _Right._Current; } - _NODISCARD_FRIEND constexpr bool operator>(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Right._Current < _Left._Current))) // strengthened requires random_access_range<_Base> { return _Right._Current < _Left._Current; } - _NODISCARD_FRIEND constexpr bool operator<=(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<=(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(!(_Right._Current < _Left._Current)))) // strengthened requires random_access_range<_Base> { return !(_Right._Current < _Left._Current); } - _NODISCARD_FRIEND constexpr bool operator>=(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>=(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(!(_Left._Current < _Right._Current)))) // strengthened requires random_access_range<_Base> { return !(_Left._Current < _Right._Current); } - _NODISCARD_FRIEND constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current <=> _Right._Current)) // strengthened requires random_access_range<_Base> && three_way_comparable<_Base_iterator> { return _Left._Current <=> _Right._Current; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const _Iterator& _It, const difference_type _Off) + _NODISCARD friend constexpr _Iterator operator+(const _Iterator& _It, const difference_type _Off) requires random_access_range<_Base> { auto _Copy = _It; @@ -6844,7 +6871,7 @@ namespace ranges { return _Copy; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const difference_type _Off, const _Iterator& _It) + _NODISCARD friend constexpr _Iterator operator+(const difference_type _Off, const _Iterator& _It) requires random_access_range<_Base> { auto _Copy = _It; @@ -6852,7 +6879,7 @@ namespace ranges { return _Copy; } - _NODISCARD_FRIEND constexpr _Iterator operator-(const _Iterator& _It, const difference_type _Off) + _NODISCARD friend constexpr _Iterator operator-(const _Iterator& _It, const difference_type _Off) requires random_access_range<_Base> { auto _Copy = _It; @@ -6860,7 +6887,7 @@ namespace ranges { return _Copy; } - _NODISCARD_FRIEND constexpr difference_type operator-(const _Iterator& _Left, const _Iterator& _Right) // + _NODISCARD friend constexpr difference_type operator-(const _Iterator& _Left, const _Iterator& _Right) // noexcept(noexcept(_Left._Current - _Right._Current)) // strengthened requires sized_sentinel_for<_Base_iterator, _Base_iterator> { @@ -6876,21 +6903,21 @@ namespace ranges { } } - _NODISCARD_FRIEND constexpr difference_type operator-(default_sentinel_t, const _Iterator& _It) noexcept( + _NODISCARD friend constexpr difference_type operator-(default_sentinel_t, const _Iterator& _It) noexcept( noexcept(_It._End - _It._Current)) // strengthened requires sized_sentinel_for<_Base_sentinel, _Base_iterator> { return _Div_ceil(_It._End - _It._Current, _It._Stride); } - _NODISCARD_FRIEND constexpr difference_type operator-(const _Iterator& _It, default_sentinel_t) noexcept( + _NODISCARD friend constexpr difference_type operator-(const _Iterator& _It, default_sentinel_t) noexcept( noexcept(_It._End - _It._Current)) // strengthened requires sized_sentinel_for<_Base_sentinel, _Base_iterator> { return -_Div_ceil(_It._End - _It._Current, _It._Stride); } - _NODISCARD_FRIEND constexpr range_rvalue_reference_t<_Base> iter_move(const _Iterator& _It) noexcept( + _NODISCARD friend constexpr range_rvalue_reference_t<_Base> iter_move(const _Iterator& _It) noexcept( noexcept(_RANGES iter_move(_It._Current))) { return _RANGES iter_move(_It._Current); } @@ -7264,7 +7291,7 @@ namespace ranges { _Current); } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Lhs, const _Iterator& _Rhs) noexcept( + _NODISCARD friend constexpr bool operator==(const _Iterator& _Lhs, const _Iterator& _Rhs) noexcept( noexcept(_Zip_iterator_sentinel_equal(_Lhs._Current, _Rhs._Current))) // strengthened requires (equality_comparable>> && ...) { @@ -7276,13 +7303,13 @@ namespace ranges { } } - _NODISCARD_FRIEND constexpr auto operator<=>(const _Iterator& _Lhs, const _Iterator& _Rhs) + _NODISCARD friend constexpr auto operator<=>(const _Iterator& _Lhs, const _Iterator& _Rhs) requires _All_random_access<_IsConst, _ViewTypes...> { return _Lhs._Current <=> _Rhs._Current; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const _Iterator& _Lhs, const difference_type _Rhs) noexcept( + _NODISCARD friend constexpr _Iterator operator+(const _Iterator& _Lhs, const difference_type _Rhs) noexcept( noexcept(_STD declval<_Iterator&>() += _Rhs) && is_nothrow_copy_constructible_v<_Iterator>) // strengthened requires _All_random_access<_IsConst, _ViewTypes...> @@ -7293,14 +7320,14 @@ namespace ranges { return _Modified_iterator; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const difference_type _Lhs, const _Iterator& _Rhs) noexcept( + _NODISCARD friend constexpr _Iterator operator+(const difference_type _Lhs, const _Iterator& _Rhs) noexcept( noexcept(_Rhs + _Lhs)) /* strengthened */ requires _All_random_access<_IsConst, _ViewTypes...> { return _Rhs + _Lhs; } - _NODISCARD_FRIEND constexpr _Iterator operator-(const _Iterator& _Lhs, const difference_type _Rhs) noexcept( + _NODISCARD friend constexpr _Iterator operator-(const _Iterator& _Lhs, const difference_type _Rhs) noexcept( noexcept(_STD declval<_Iterator&>() -= _Rhs) && is_nothrow_copy_constructible_v<_Iterator>) // strengthened requires _All_random_access<_IsConst, _ViewTypes...> @@ -7311,7 +7338,7 @@ namespace ranges { return _Modified_iterator; } - _NODISCARD_FRIEND constexpr difference_type + _NODISCARD friend constexpr difference_type operator-(const _Iterator& _Lhs, const _Iterator& _Rhs) noexcept( noexcept(_Zip_get_smallest_distance(_STD declval<_My_tuple>(), _STD declval<_My_tuple>()))) // strengthened @@ -7322,7 +7349,7 @@ namespace ranges { return _Zip_get_smallest_distance(_Lhs._Current, _Rhs._Current); } - _NODISCARD_FRIEND constexpr auto iter_move(const _Iterator& _Itr) noexcept( + _NODISCARD friend constexpr auto iter_move(const _Iterator& _Itr) noexcept( (noexcept(_RANGES iter_move(_STD declval>&>())) && ...) && (is_nothrow_move_constructible_v>> @@ -7383,7 +7410,7 @@ namespace ranges { requires (sentinel_for>, iterator_t<_Maybe_const<_IteratorConst, _ViewTypes>>> && ...) - _NODISCARD_FRIEND constexpr bool + _NODISCARD friend constexpr bool operator==(const _Iterator<_IteratorConst>& _Lhs, const _Sentinel& _Rhs) noexcept( noexcept(_Zip_iterator_sentinel_equal(_Get_iterator_tuple(_Lhs), _Rhs._End))) /* strengthened */ { return _Zip_iterator_sentinel_equal(_Get_iterator_tuple(_Lhs), _Rhs._End); @@ -7393,7 +7420,7 @@ namespace ranges { requires (sized_sentinel_for>, iterator_t<_Maybe_const<_IteratorConst, _ViewTypes>>> && ...) - _NODISCARD_FRIEND constexpr common_type_t>...> + _NODISCARD friend constexpr common_type_t>...> operator-(const _Iterator<_IteratorConst>& _Lhs, const _Sentinel& _Rhs) noexcept( noexcept(_Zip_get_smallest_distance< common_type_t>...>>( @@ -7406,7 +7433,7 @@ namespace ranges { requires (sized_sentinel_for>, iterator_t<_Maybe_const<_IteratorConst, _ViewTypes>>> && ...) - _NODISCARD_FRIEND constexpr common_type_t>...> + _NODISCARD friend constexpr common_type_t>...> operator-(const _Sentinel& _Lhs, const _Iterator<_IteratorConst>& _Rhs) noexcept( noexcept(-(_Rhs - _Lhs))) /* strengthened */ { return -(_Rhs - _Lhs); @@ -7679,42 +7706,42 @@ namespace ranges { return _STD apply(_Subscript_closure(_Where), _Inner._Current); } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Lhs, const _Iterator& _Rhs) noexcept( + _NODISCARD friend constexpr bool operator==(const _Iterator& _Lhs, const _Iterator& _Rhs) noexcept( noexcept(_Lhs._Inner == _Rhs._Inner)) // strengthened requires equality_comparable<_Ziperator<_IsConst>> { return _Lhs._Inner == _Rhs._Inner; } - _NODISCARD_FRIEND constexpr auto operator<=>(const _Iterator& _Lhs, const _Iterator& _Rhs) noexcept( + _NODISCARD friend constexpr auto operator<=>(const _Iterator& _Lhs, const _Iterator& _Rhs) noexcept( noexcept(_Lhs._Inner <=> _Rhs._Inner)) // strengthened requires random_access_range<_Base_t> { return _Lhs._Inner <=> _Rhs._Inner; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const _Iterator& _Lhs, const difference_type _Rhs) noexcept( + _NODISCARD friend constexpr _Iterator operator+(const _Iterator& _Lhs, const difference_type _Rhs) noexcept( noexcept(_Iterator{*_Lhs._Parent, _Lhs._Inner + _Rhs})) // strengthened requires random_access_range<_Base_t> { return _Iterator{*_Lhs._Parent, _Lhs._Inner + _Rhs}; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const difference_type _Lhs, const _Iterator& _Rhs) noexcept( + _NODISCARD friend constexpr _Iterator operator+(const difference_type _Lhs, const _Iterator& _Rhs) noexcept( noexcept(_Iterator{*_Rhs._Parent, _Rhs._Inner + _Lhs})) // strengthened requires random_access_range<_Base_t> { return _Iterator{*_Rhs._Parent, _Rhs._Inner + _Lhs}; } - _NODISCARD_FRIEND constexpr _Iterator operator-(const _Iterator& _Lhs, const difference_type _Rhs) noexcept( + _NODISCARD friend constexpr _Iterator operator-(const _Iterator& _Lhs, const difference_type _Rhs) noexcept( noexcept(_Iterator{*_Lhs._Parent, _Lhs._Inner - _Rhs})) // strengthened requires random_access_range<_Base_t> { return _Iterator{*_Lhs._Parent, _Lhs._Inner - _Rhs}; } - _NODISCARD_FRIEND constexpr difference_type operator-(const _Iterator& _Lhs, + _NODISCARD friend constexpr difference_type operator-(const _Iterator& _Lhs, const _Iterator& _Rhs) noexcept(noexcept(_Lhs._Inner - _Rhs._Inner)) // strengthened requires sized_sentinel_for<_Ziperator<_IsConst>, _Ziperator<_IsConst>> { @@ -7768,14 +7795,14 @@ namespace ranges { template requires sentinel_for<_Zentinel<_IsConst>, _Ziperator<_IteratorConst>> - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator<_IteratorConst>& _Lhs, + _NODISCARD friend constexpr bool operator==(const _Iterator<_IteratorConst>& _Lhs, const _Sentinel& _Rhs) noexcept(noexcept(_Get_iterator_inner(_Lhs) == _Rhs._Inner)) /* strengthened */ { return _Get_iterator_inner(_Lhs) == _Rhs._Inner; } template requires sized_sentinel_for<_Zentinel<_IsConst>, _Ziperator<_IteratorConst>> - _NODISCARD_FRIEND constexpr _Iter_sent_difference_type<_IteratorConst> // TRANSITION, DevCom-10253131 + _NODISCARD friend constexpr _Iter_sent_difference_type<_IteratorConst> // TRANSITION, DevCom-10253131 operator-(const _Iterator<_IteratorConst>& _Lhs, const _Sentinel & _Rhs) noexcept( noexcept(_Get_iterator_inner(_Lhs) - _Rhs._Inner)) /* strengthened */ { return _Get_iterator_inner(_Lhs) - _Rhs._Inner; @@ -7783,7 +7810,7 @@ namespace ranges { template requires sized_sentinel_for<_Zentinel<_IsConst>, _Ziperator<_IteratorConst>> - _NODISCARD_FRIEND constexpr _Iter_sent_difference_type<_IteratorConst> // TRANSITION, DevCom-10253131 + _NODISCARD friend constexpr _Iter_sent_difference_type<_IteratorConst> // TRANSITION, DevCom-10253131 operator-(const _Sentinel & _Lhs, const _Iterator<_IteratorConst>& _Rhs) noexcept( noexcept(_Lhs._Inner - _Get_iterator_inner(_Rhs))) /* strengthened */ { return _Lhs._Inner - _Get_iterator_inner(_Rhs); @@ -8085,48 +8112,48 @@ namespace ranges { return _RANGES _Tuple_transform([&](auto& _It) -> decltype(auto) { return _It[_Off]; }, _Current); } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Left._Current.back() == _Right._Current.back()))) // strengthened { return _Left._Current.back() == _Right._Current.back(); } - _NODISCARD_FRIEND constexpr bool operator<(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Left._Current.back() < _Right._Current.back()))) // strengthened requires random_access_range<_Base> { return _Left._Current.back() < _Right._Current.back(); } - _NODISCARD_FRIEND constexpr bool operator>(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Right < _Left)) // strengthened requires random_access_range<_Base> { return _Right < _Left; } - _NODISCARD_FRIEND constexpr bool operator<=(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<=(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(!(_Right < _Left))) // strengthened requires random_access_range<_Base> { return !(_Right < _Left); } - _NODISCARD_FRIEND constexpr bool operator>=(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>=(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(!(_Left < _Right))) // strengthened requires random_access_range<_Base> { return !(_Left < _Right); } - _NODISCARD_FRIEND constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current.back() <=> _Right._Current.back())) // strengthened requires random_access_range<_Base> && three_way_comparable<_Base_iterator> { return _Left._Current.back() <=> _Right._Current.back(); } - _NODISCARD_FRIEND constexpr _Iterator operator+(const _Iterator& _It, const difference_type _Off) noexcept( + _NODISCARD friend constexpr _Iterator operator+(const _Iterator& _It, const difference_type _Off) noexcept( noexcept(_STD declval<_Iterator&>() += _Off) && is_nothrow_copy_constructible_v<_Iterator>) // strengthened requires random_access_range<_Base> @@ -8136,7 +8163,7 @@ namespace ranges { return _Tmp; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const difference_type _Off, const _Iterator& _It) noexcept( + _NODISCARD friend constexpr _Iterator operator+(const difference_type _Off, const _Iterator& _It) noexcept( noexcept(_STD declval<_Iterator&>() += _Off) && is_nothrow_copy_constructible_v<_Iterator>) // strengthened requires random_access_range<_Base> @@ -8146,7 +8173,7 @@ namespace ranges { return _Tmp; } - _NODISCARD_FRIEND constexpr _Iterator operator-(const _Iterator& _It, const difference_type _Off) noexcept( + _NODISCARD friend constexpr _Iterator operator-(const _Iterator& _It, const difference_type _Off) noexcept( noexcept(_STD declval<_Iterator&>() -= _Off) && is_nothrow_copy_constructible_v<_Iterator>) // strengthened requires random_access_range<_Base> @@ -8156,7 +8183,7 @@ namespace ranges { return _Tmp; } - _NODISCARD_FRIEND constexpr difference_type + _NODISCARD friend constexpr difference_type operator-(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Current.back() - _Right._Current.back())) // strengthened requires sized_sentinel_for<_Base_iterator, _Base_iterator> @@ -8164,7 +8191,7 @@ namespace ranges { return _Left._Current.back() - _Right._Current.back(); } - _NODISCARD_FRIEND constexpr auto iter_move(const _Iterator& _It) noexcept( + _NODISCARD friend constexpr auto iter_move(const _Iterator& _It) noexcept( noexcept(_RANGES iter_move(_STD declval())) && is_nothrow_move_constructible_v>) { return _RANGES _Tuple_transform(_RANGES iter_move, _It._Current); @@ -8218,14 +8245,14 @@ namespace ranges { template requires sentinel_for<_Base_sentinel, iterator_t<_Maybe_const<_OtherConst, _Vw>>> - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator<_OtherConst>& _It, + _NODISCARD friend constexpr bool operator==(const _Iterator<_OtherConst>& _It, const _Sentinel& _Se) noexcept(noexcept(_Se._Equal(_It))) /* strengthened */ { return _Se._Equal(_It); } template requires sized_sentinel_for<_Base_sentinel, iterator_t<_Maybe_const<_OtherConst, _Vw>>> - _NODISCARD_FRIEND constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-( + _NODISCARD friend constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-( const _Iterator<_OtherConst>& _It, const _Sentinel& _Se) noexcept( // noexcept(_Se._Distance_from(_It))) /* strengthened */ { return -_Se._Distance_from(_It); @@ -8233,7 +8260,7 @@ namespace ranges { template requires sized_sentinel_for<_Base_sentinel, iterator_t<_Maybe_const<_OtherConst, _Vw>>> - _NODISCARD_FRIEND constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-( + _NODISCARD friend constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-( const _Sentinel& _Se, const _Iterator<_OtherConst>& _It) noexcept( // noexcept(_Se._Distance_from(_It))) /* strengthened */ { return _Se._Distance_from(_It); @@ -8343,7 +8370,7 @@ namespace ranges { template _NODISCARD _STATIC_CALL_OPERATOR constexpr auto operator()(_Rng&&) _CONST_CALL_OPERATOR noexcept - requires (_Nx == 0) + requires (_Nx == 0) && forward_range<_Rng> { return empty_view>{}; } @@ -8481,68 +8508,68 @@ namespace ranges { _Inner._Current); } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Inner == _Right._Inner)) /* strengthened */ { return _Left._Inner == _Right._Inner; } - _NODISCARD_FRIEND constexpr bool operator<(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Inner < _Right._Inner)) // strengthened requires random_access_range<_Base> { return _Left._Inner < _Right._Inner; } - _NODISCARD_FRIEND constexpr bool operator>(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Inner > _Right._Inner)) // strengthened requires random_access_range<_Base> { return _Left._Inner > _Right._Inner; } - _NODISCARD_FRIEND constexpr bool operator<=(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<=(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Inner <= _Right._Inner)) // strengthened requires random_access_range<_Base> { return _Left._Inner <= _Right._Inner; } - _NODISCARD_FRIEND constexpr bool operator>=(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>=(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Inner >= _Right._Inner)) // strengthened requires random_access_range<_Base> { return _Left._Inner >= _Right._Inner; } - _NODISCARD_FRIEND constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) noexcept( + _NODISCARD friend constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) noexcept( noexcept(_Left._Inner <=> _Right._Inner)) // strengthened requires random_access_range<_Base> && three_way_comparable<_Inner_iterator<_Const>> { return _Left._Inner <=> _Right._Inner; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const _Iterator& _It, const difference_type _Off) noexcept( + _NODISCARD friend constexpr _Iterator operator+(const _Iterator& _It, const difference_type _Off) noexcept( noexcept(_It._Inner + _Off) && is_nothrow_move_constructible_v<_Inner_iterator<_Const>>) // strengthened requires random_access_range<_Base> { return _Iterator{*_It._Parent, _It._Inner + _Off}; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const difference_type _Off, const _Iterator& _It) noexcept( + _NODISCARD friend constexpr _Iterator operator+(const difference_type _Off, const _Iterator& _It) noexcept( noexcept(_It._Inner + _Off) && is_nothrow_move_constructible_v<_Inner_iterator<_Const>>) // strengthened requires random_access_range<_Base> { return _Iterator{*_It._Parent, _It._Inner + _Off}; } - _NODISCARD_FRIEND constexpr _Iterator operator-(const _Iterator& _It, const difference_type _Off) noexcept( + _NODISCARD friend constexpr _Iterator operator-(const _Iterator& _It, const difference_type _Off) noexcept( noexcept(_It._Inner - _Off) && is_nothrow_move_constructible_v<_Inner_iterator<_Const>>) // strengthened requires random_access_range<_Base> { return _Iterator{*_It._Parent, _It._Inner - _Off}; } - _NODISCARD_FRIEND constexpr difference_type operator-(const _Iterator& _Left, const _Iterator& _Right) // + _NODISCARD friend constexpr difference_type operator-(const _Iterator& _Left, const _Iterator& _Right) // noexcept(noexcept(_Left._Inner - _Right._Inner)) // strengthened requires sized_sentinel_for<_Inner_iterator<_Const>, _Inner_iterator<_Const>> { @@ -8582,14 +8609,14 @@ namespace ranges { template requires sentinel_for<_Inner_sentinel<_Const>, _Inner_iterator<_OtherConst>> - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator<_OtherConst>& _It, + _NODISCARD friend constexpr bool operator==(const _Iterator<_OtherConst>& _It, const _Sentinel& _Se) noexcept(noexcept(_Se._Equal(_It))) /* strengthened */ { return _Se._Equal(_It); } template requires sized_sentinel_for<_Inner_sentinel<_Const>, _Inner_iterator<_OtherConst>> - _NODISCARD_FRIEND constexpr range_difference_t<_Maybe_const<_OtherConst, _Inner_view>> operator-( + _NODISCARD friend constexpr range_difference_t<_Maybe_const<_OtherConst, _Inner_view>> operator-( const _Iterator<_OtherConst>& _It, const _Sentinel& _Se) noexcept( // noexcept(_Se._Distance_from(_It))) /* strengthened */ { return -_Se._Distance_from(_It); @@ -8597,7 +8624,7 @@ namespace ranges { template requires sized_sentinel_for<_Inner_sentinel<_Const>, _Inner_iterator<_OtherConst>> - _NODISCARD_FRIEND constexpr range_difference_t<_Maybe_const<_OtherConst, _Inner_view>> operator-( + _NODISCARD friend constexpr range_difference_t<_Maybe_const<_OtherConst, _Inner_view>> operator-( const _Sentinel& _Se, const _Iterator<_OtherConst>& _It) noexcept( // noexcept(_Se._Distance_from(_It))) /* strengthened */ { return _Se._Distance_from(_It); @@ -8679,7 +8706,8 @@ namespace ranges { template _NODISCARD _STATIC_CALL_OPERATOR constexpr auto operator()(_Rng&&, _Fn&& _Func) _CONST_CALL_OPERATOR noexcept(noexcept(views::zip_transform(_STD forward<_Fn>(_Func)))) - requires (_Nx == 0) && requires { views::zip_transform(_STD forward<_Fn>(_Func)); } + requires (_Nx == 0) + && forward_range<_Rng> && requires { views::zip_transform(_STD forward<_Fn>(_Func)); } { return views::zip_transform(_STD forward<_Fn>(_Func)); } @@ -9004,59 +9032,59 @@ namespace ranges { return *(*this + _Off); } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) + _NODISCARD friend constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) requires equality_comparable>> { return _Left._Current == _Right._Current; } - _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _It, default_sentinel_t) { + _NODISCARD friend constexpr bool operator==(const _Iterator& _It, default_sentinel_t) { return _It._Is_end(make_index_sequence<1 + sizeof...(_Rest)>{}); } - _NODISCARD_FRIEND constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) + _NODISCARD friend constexpr auto operator<=>(const _Iterator& _Left, const _Iterator& _Right) requires _All_random_access<_Const, _First, _Rest...> { return _Left._Current <=> _Right._Current; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const _Iterator& _It, const difference_type _Off) + _NODISCARD friend constexpr _Iterator operator+(const _Iterator& _It, const difference_type _Off) requires _Cartesian_product_is_random_access<_Const, _First, _Rest...> { return _Iterator{_It} += _Off; } - _NODISCARD_FRIEND constexpr _Iterator operator+(const difference_type _Off, const _Iterator& _It) + _NODISCARD friend constexpr _Iterator operator+(const difference_type _Off, const _Iterator& _It) requires _Cartesian_product_is_random_access<_Const, _First, _Rest...> { return _It + _Off; } - _NODISCARD_FRIEND constexpr _Iterator operator-(const _Iterator& _It, const difference_type _Off) + _NODISCARD friend constexpr _Iterator operator-(const _Iterator& _It, const difference_type _Off) requires _Cartesian_product_is_random_access<_Const, _First, _Rest...> { return _Iterator{_It} -= _Off; } - _NODISCARD_FRIEND constexpr difference_type operator-(const _Iterator& _Left, const _Iterator& _Right) + _NODISCARD friend constexpr difference_type operator-(const _Iterator& _Left, const _Iterator& _Right) requires _Cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Rest...> { return _Left._Distance_from(_Right._Current); } - _NODISCARD_FRIEND constexpr difference_type operator-(const _Iterator& _It, default_sentinel_t) + _NODISCARD friend constexpr difference_type operator-(const _Iterator& _It, default_sentinel_t) requires _Cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Rest...> { return _It._Distance_from(_It._End_tuple(make_index_sequence{})); } - _NODISCARD_FRIEND constexpr difference_type operator-(default_sentinel_t _Se, const _Iterator& _It) + _NODISCARD friend constexpr difference_type operator-(default_sentinel_t _Se, const _Iterator& _It) requires _Cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Rest...> { return -(_It - _Se); } - _NODISCARD_FRIEND constexpr auto iter_move(const _Iterator& _It) noexcept( + _NODISCARD friend constexpr auto iter_move(const _Iterator& _It) noexcept( _Is_iter_move_nothrow(make_index_sequence<1 + sizeof...(_Rest)>{})) { return _RANGES _Tuple_transform(_RANGES iter_move, _It._Current); } diff --git a/stl/inc/span b/stl/inc/span index d18667c64fc..018bc98cc98 100644 --- a/stl/inc/span +++ b/stl/inc/span @@ -110,7 +110,7 @@ struct _Span_iterator { return _Tmp; } - _NODISCARD_FRIEND constexpr _Span_iterator operator+(const difference_type _Off, _Span_iterator _Next) noexcept { + _NODISCARD friend constexpr _Span_iterator operator+(const difference_type _Off, _Span_iterator _Next) noexcept { _Next += _Off; return _Next; } diff --git a/stl/inc/stacktrace b/stl/inc/stacktrace index cc182e617d9..b5b57c00c9b 100644 --- a/stl/inc/stacktrace +++ b/stl/inc/stacktrace @@ -107,9 +107,9 @@ public: return __std_stacktrace_source_line(_Address); } - _NODISCARD_FRIEND constexpr bool operator==(const stacktrace_entry&, const stacktrace_entry&) noexcept = default; + _NODISCARD friend constexpr bool operator==(const stacktrace_entry&, const stacktrace_entry&) noexcept = default; - _NODISCARD_FRIEND constexpr strong_ordering operator<=>( + _NODISCARD friend constexpr strong_ordering operator<=>( const stacktrace_entry&, const stacktrace_entry&) noexcept = default; private: @@ -253,12 +253,12 @@ public: } template - _NODISCARD_FRIEND bool operator==(const basic_stacktrace& _Lhs, const basic_stacktrace<_Al2>& _Rhs) noexcept { + _NODISCARD friend bool operator==(const basic_stacktrace& _Lhs, const basic_stacktrace<_Al2>& _Rhs) noexcept { return _Lhs._Hash == _Rhs._Hash && _STD equal(_Lhs.begin(), _Lhs.end(), _Rhs.begin(), _Rhs.end()); } template - _NODISCARD_FRIEND strong_ordering operator<=>( + _NODISCARD friend strong_ordering operator<=>( const basic_stacktrace& _Lhs, const basic_stacktrace<_Al2>& _Rhs) noexcept { const auto _Result = _Lhs._Frames.size() <=> _Rhs._Frames.size(); if (_Result != strong_ordering::equal) { diff --git a/stl/inc/stop_token b/stl/inc/stop_token index 5702d902199..6e37adb0158 100644 --- a/stl/inc/stop_token +++ b/stl/inc/stop_token @@ -162,7 +162,7 @@ public: return _Local != nullptr && _Local->_Stop_possible(); } - _NODISCARD_FRIEND bool operator==(const stop_token& _Lhs, const stop_token& _Rhs) noexcept = default; + _NODISCARD friend bool operator==(const stop_token& _Lhs, const stop_token& _Rhs) noexcept = default; friend void swap(stop_token& _Lhs, stop_token& _Rhs) noexcept { _STD swap(_Lhs._State, _Rhs._State); @@ -234,7 +234,7 @@ public: return _Local && _Local->_Request_stop(); } - _NODISCARD_FRIEND bool operator==(const stop_source& _Lhs, const stop_source& _Rhs) noexcept = default; + _NODISCARD friend bool operator==(const stop_source& _Lhs, const stop_source& _Rhs) noexcept = default; friend void swap(stop_source& _Lhs, stop_source& _Rhs) noexcept { _STD swap(_Lhs._State, _Rhs._State); diff --git a/stl/inc/system_error b/stl/inc/system_error index b8697d328cc..66ef51bb0fc 100644 --- a/stl/inc/system_error +++ b/stl/inc/system_error @@ -212,39 +212,39 @@ public: } #if _STL_OPTIMIZE_SYSTEM_ERROR_OPERATORS - _NODISCARD_FRIEND bool operator==(const error_code& _Left, const error_code& _Right) noexcept { + _NODISCARD friend bool operator==(const error_code& _Left, const error_code& _Right) noexcept { return _Left.category() == _Right.category() && _Left.value() == _Right.value(); } - _NODISCARD_FRIEND bool operator==(const error_code& _Left, const error_condition& _Right) noexcept { + _NODISCARD friend bool operator==(const error_code& _Left, const error_condition& _Right) noexcept { return _System_error_equal(_Left, _Right); } #if _HAS_CXX20 - _NODISCARD_FRIEND strong_ordering operator<=>(const error_code& _Left, const error_code& _Right) noexcept { + _NODISCARD friend strong_ordering operator<=>(const error_code& _Left, const error_code& _Right) noexcept { if (const auto _Result = _Left.category() <=> _Right.category(); _Result != 0) { return _Result; } return _Left.value() <=> _Right.value(); } #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv - _NODISCARD_FRIEND bool operator<(const error_code& _Left, const error_code& _Right) noexcept { + _NODISCARD friend bool operator<(const error_code& _Left, const error_code& _Right) noexcept { return _Left.category() < _Right.category() || (_Left.category() == _Right.category() && _Left.value() < _Right.value()); } - _NODISCARD_FRIEND bool operator==(const error_condition& _Left, const error_code& _Right) noexcept { + _NODISCARD friend bool operator==(const error_condition& _Left, const error_code& _Right) noexcept { return _System_error_equal(_Right, _Left); } - _NODISCARD_FRIEND bool operator!=(const error_code& _Left, const error_code& _Right) noexcept { + _NODISCARD friend bool operator!=(const error_code& _Left, const error_code& _Right) noexcept { return !(_Left == _Right); } - _NODISCARD_FRIEND bool operator!=(const error_code& _Left, const error_condition& _Right) noexcept { + _NODISCARD friend bool operator!=(const error_code& _Left, const error_condition& _Right) noexcept { return !_System_error_equal(_Left, _Right); } - _NODISCARD_FRIEND bool operator!=(const error_condition& _Left, const error_code& _Right) noexcept { + _NODISCARD friend bool operator!=(const error_condition& _Left, const error_code& _Right) noexcept { return !_System_error_equal(_Right, _Left); } #endif // ^^^ !_HAS_CXX20 ^^^ @@ -301,12 +301,12 @@ public: } #if _STL_OPTIMIZE_SYSTEM_ERROR_OPERATORS - _NODISCARD_FRIEND bool operator==(const error_condition& _Left, const error_condition& _Right) noexcept { + _NODISCARD friend bool operator==(const error_condition& _Left, const error_condition& _Right) noexcept { return _Left.category() == _Right.category() && _Left.value() == _Right.value(); } #if _HAS_CXX20 - _NODISCARD_FRIEND strong_ordering operator<=>( + _NODISCARD friend strong_ordering operator<=>( const error_condition& _Left, const error_condition& _Right) noexcept { if (const auto _Result = _Left.category() <=> _Right.category(); _Result != 0) { return _Result; @@ -314,11 +314,11 @@ public: return _Left.value() <=> _Right.value(); } #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv - _NODISCARD_FRIEND bool operator<(const error_condition& _Left, const error_condition& _Right) noexcept { + _NODISCARD friend bool operator<(const error_condition& _Left, const error_condition& _Right) noexcept { return _Left.category() < _Right.category() || (_Left.category() == _Right.category() && _Left.value() < _Right.value()); } - _NODISCARD_FRIEND bool operator!=(const error_condition& _Left, const error_condition& _Right) noexcept { + _NODISCARD friend bool operator!=(const error_condition& _Left, const error_condition& _Right) noexcept { return !(_Left == _Right); } #endif // ^^^ !_HAS_CXX20 ^^^ diff --git a/stl/inc/tuple b/stl/inc/tuple index b9fa78920dd..0f79be7872e 100644 --- a/stl/inc/tuple +++ b/stl/inc/tuple @@ -119,16 +119,6 @@ struct _Tuple_perfect_val, _Uty0, _Uty1, _Uty2> : bool_constant, allocator_arg_t>>, is_same<_Remove_cvref_t<_Ty0>, allocator_arg_t>>> {}; -struct _Ignore { // struct that ignores assignments - template - constexpr const _Ignore& operator=(const _Ty&) const noexcept /* strengthened */ { - // do nothing - return *this; - } -}; - -_EXPORT_STD _INLINE_VAR constexpr _Ignore ignore{}; - // Note: To improve throughput, this file uses extra _STD qualification for names that appear in the // arguments of enable_if_t. Specifically, we qualify names which appear anywhere in the STL as members of // some class - including injected-class-names! - that we know are not members of the class being defined. @@ -288,14 +278,14 @@ public: #if _HAS_CXX23 template <_Tuple_like_non_tuple _Other> - _NODISCARD_FRIEND constexpr bool operator==(const tuple&, const _Other&) noexcept /* strengthened */ { + _NODISCARD friend constexpr bool operator==(const tuple&, const _Other&) noexcept /* strengthened */ { static_assert(tuple_size_v<_Other> == 0, "Cannot compare tuples of different sizes (N4950 [tuple.rel]/2)."); return true; } template <_Tuple_like_non_tuple _Other> requires (tuple_size_v> == 0) - _NODISCARD_FRIEND constexpr strong_ordering operator<=>(const tuple&, const _Other&) noexcept /* strengthened */ { + _NODISCARD friend constexpr strong_ordering operator<=>(const tuple&, const _Other&) noexcept /* strengthened */ { return strong_ordering::equal; } #endif // _HAS_CXX23 @@ -563,12 +553,11 @@ public: } #if _HAS_CXX23 - template , - _STD _Is_copy_assignable_no_precondition_check...>, - int> = 0> + template + requires conjunction_v<_STD _Is_copy_assignable_no_precondition_check, + _STD _Is_copy_assignable_no_precondition_check...> constexpr const tuple& operator=(_Identity_t _Right) const - noexcept(conjunction_v, + noexcept(conjunction_v, is_nothrow_copy_assignable...>) /* strengthened */ { _Myfirst._Val = _Right._Myfirst._Val; _Get_rest() = _Right._Get_rest(); @@ -588,12 +577,11 @@ public: } #if _HAS_CXX23 - template , - _STD _Is_assignable_no_precondition_check...>, - int> = 0> + template + requires conjunction_v<_STD _Is_assignable_no_precondition_check, + _STD _Is_assignable_no_precondition_check...> constexpr const tuple& operator=(_Identity_t<_Myself&&> _Right) const - noexcept(conjunction_v, + noexcept(conjunction_v, is_nothrow_assignable...>) /* strengthened */ { _Myfirst._Val = _STD forward<_This>(_Right._Myfirst._Val); _Get_rest() = _STD forward<_Mybase>(_Right._Get_rest()); @@ -612,9 +600,8 @@ public: } #if _HAS_CXX23 - template >>, - _STD _Tuple_assignable_val>, - int> = 0> + template + requires (!is_same_v>) && _Tuple_assignable_v constexpr const tuple& operator=(const tuple<_Other...>& _Right) const noexcept(_Tuple_nothrow_assignable_v) /* strengthened */ { _Myfirst._Val = _Right._Myfirst._Val; @@ -634,9 +621,8 @@ public: } #if _HAS_CXX23 - template >>, - _STD _Tuple_assignable_val>, - int> = 0> + template + requires (!is_same_v>) && _Tuple_assignable_v constexpr const tuple& operator=(tuple<_Other...>&& _Right) const noexcept(_Tuple_nothrow_assignable_v) /* strengthened */ { _Myfirst._Val = _STD forward::_This_type>(_Right._Myfirst._Val); @@ -655,8 +641,8 @@ public: } #if _HAS_CXX23 - template , int> = 0> + template + requires _Tuple_assignable_v constexpr const tuple& operator=(const pair<_First, _Second>& _Right) const noexcept(_Tuple_nothrow_assignable_v) /* strengthened */ { _Myfirst._Val = _Right.first; @@ -674,7 +660,8 @@ public: } #if _HAS_CXX23 - template , int> = 0> + template + requires _Tuple_assignable_v constexpr const tuple& operator=(pair<_First, _Second>&& _Right) const noexcept(_Tuple_nothrow_assignable_v) /* strengthened */ { _Myfirst._Val = _STD forward<_First>(_Right.first); @@ -781,7 +768,7 @@ public: } template <_Tuple_like_non_tuple _Other> - _NODISCARD_FRIEND constexpr bool operator==(const tuple& _Left, const _Other& _Right) { + _NODISCARD friend constexpr bool operator==(const tuple& _Left, const _Other& _Right) { static_assert(1 + sizeof...(_Rest) == tuple_size_v<_Other>, "Cannot compare tuples of different sizes (N4950 [tuple.rel]/2)."); static_assert(_Can_equal_compare_with_tuple_like_v<_Other>, @@ -799,7 +786,7 @@ public: } template <_Tuple_like_non_tuple _Other> - _NODISCARD_FRIEND constexpr auto operator<=>(const tuple& _Left, const _Other& _Right) + _NODISCARD friend constexpr auto operator<=>(const tuple& _Left, const _Other& _Right) -> _Three_way_comparison_result_with_tuple_like_t { return _Left._Three_way_compare_with_tuple_like(_Right, make_index_sequence<1 + sizeof...(_Rest)>{}); } @@ -906,7 +893,8 @@ _CONSTEXPR20 void swap(tuple<_Types...>& _Left, tuple<_Types...>& _Right) noexce } #if _HAS_CXX23 -_EXPORT_STD template ...>, int> = 0> +_EXPORT_STD template + requires conjunction_v...> constexpr void swap(const tuple<_Types...>& _Left, const tuple<_Types...>& _Right) noexcept( noexcept(_Left.swap(_Right))) { _Left.swap(_Right); diff --git a/stl/inc/utility b/stl/inc/utility index d5e58acc007..df825320fd6 100644 --- a/stl/inc/utility +++ b/stl/inc/utility @@ -134,6 +134,16 @@ _EXPORT_STD struct piecewise_construct_t { // tag type for pair tuple arguments _EXPORT_STD _INLINE_VAR constexpr piecewise_construct_t piecewise_construct{}; +struct _Ignore { // struct that ignores assignments + template + constexpr const _Ignore& operator=(const _Ty&) const noexcept { + // do nothing + return *this; + } +}; + +_EXPORT_STD _INLINE_VAR constexpr _Ignore ignore{}; + _EXPORT_STD template class tuple; @@ -251,8 +261,8 @@ struct pair { // store a pair of values pair(pair&&) = default; #if _HAS_CXX23 - template , is_constructible<_Ty2, _Other2&>>, int> = 0> + template + requires is_constructible_v<_Ty1, _Other1&> && is_constructible_v<_Ty2, _Other2&> constexpr explicit(!conjunction_v, is_convertible<_Other2&, _Ty2>>) pair(pair<_Other1, _Other2>& _Right) noexcept( is_nothrow_constructible_v<_Ty1, _Other1&> && is_nothrow_constructible_v<_Ty2, _Other2&>) // strengthened @@ -276,9 +286,8 @@ struct pair { // store a pair of values : first(_STD forward<_Other1>(_Right.first)), second(_STD forward<_Other2>(_Right.second)) {} #if _HAS_CXX23 - template , is_constructible<_Ty2, const _Other2>>, int> = - 0> + template + requires is_constructible_v<_Ty1, const _Other1> && is_constructible_v<_Ty2, const _Other2> constexpr explicit(!conjunction_v, is_convertible>) pair(const pair<_Other1, _Other2>&& _Right) noexcept( is_nothrow_constructible_v<_Ty1, const _Other1> @@ -325,10 +334,9 @@ struct pair { // store a pair of values } #if _HAS_CXX23 - template , - _Is_copy_assignable_no_precondition_check>, - int> = 0> + template + requires _Is_copy_assignable_unchecked_v + && _Is_copy_assignable_unchecked_v constexpr const pair& operator=(_Identity_t _Right) const noexcept(conjunction_v, is_nothrow_copy_assignable>) /* strengthened */ { @@ -350,10 +358,9 @@ struct pair { // store a pair of values } #if _HAS_CXX23 - template , - _Is_assignable_no_precondition_check>, - int> = 0> + template + requires _Is_assignable_no_precondition_check::value + && _Is_assignable_no_precondition_check::value constexpr const pair& operator=(_Identity_t<_Myself&&> _Right) const noexcept(conjunction_v, is_nothrow_assignable>) /* strengthened */ { @@ -376,10 +383,9 @@ struct pair { // store a pair of values } #if _HAS_CXX23 - template >>, - is_assignable, is_assignable>, - int> = 0> + template + requires (!is_same_v>) + && is_assignable_v && is_assignable_v constexpr const pair& operator=(const pair<_Other1, _Other2>& _Right) const noexcept(is_nothrow_assignable_v && is_nothrow_assignable_v) /* strengthened */ { @@ -401,10 +407,9 @@ struct pair { // store a pair of values } #if _HAS_CXX23 - template >>, is_assignable, - is_assignable>, - int> = 0> + template + requires (!is_same_v>) + && is_assignable_v && is_assignable_v constexpr const pair& operator=(pair<_Other1, _Other2>&& _Right) const noexcept(is_nothrow_assignable_v && is_nothrow_assignable_v) /* strengthened */ { @@ -471,8 +476,8 @@ _CONSTEXPR20 void swap(pair<_Ty1, _Ty2>& _Left, pair<_Ty1, _Ty2>& _Right) noexce } #if _HAS_CXX23 -_EXPORT_STD template && is_swappable_v, int> = 0> +_EXPORT_STD template + requires is_swappable::value && is_swappable::value // TRANSITION, /permissive needs ::value constexpr void swap(const pair<_Ty1, _Ty2>& _Left, const pair<_Ty1, _Ty2>& _Right) noexcept( noexcept(_Left.swap(_Right))) { _Left.swap(_Right); @@ -784,14 +789,9 @@ _EXPORT_STD template constexpr in_place_index_t<_Idx> in_place_index{}; #endif // _HAS_CXX17 -template -constexpr bool _Is_standard_integer = _Is_any_of_v, signed char, short, int, long, long long, - unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>; - template _NODISCARD constexpr bool _Cmp_equal(const _Ty1 _Left, const _Ty2 _Right) noexcept { - static_assert(_Is_standard_integer<_Ty1> && _Is_standard_integer<_Ty2>, - "The integer comparison functions only accept standard and extended integer types."); + _STL_INTERNAL_STATIC_ASSERT(_Is_nonbool_integral<_Ty1> && _Is_nonbool_integral<_Ty2>); // allows character types if constexpr (is_signed_v<_Ty1> == is_signed_v<_Ty2>) { return _Left == _Right; } else if constexpr (is_signed_v<_Ty2>) { @@ -808,8 +808,7 @@ _NODISCARD constexpr bool _Cmp_not_equal(const _Ty1 _Left, const _Ty2 _Right) no template _NODISCARD constexpr bool _Cmp_less(const _Ty1 _Left, const _Ty2 _Right) noexcept { - static_assert(_Is_standard_integer<_Ty1> && _Is_standard_integer<_Ty2>, - "The integer comparison functions only accept standard and extended integer types."); + _STL_INTERNAL_STATIC_ASSERT(_Is_nonbool_integral<_Ty1> && _Is_nonbool_integral<_Ty2>); // allows character types if constexpr (is_signed_v<_Ty1> == is_signed_v<_Ty2>) { return _Left < _Right; } else if constexpr (is_signed_v<_Ty2>) { @@ -858,8 +857,7 @@ _NODISCARD constexpr _Ty _Max_limit() noexcept { // same as (numeric_limits<_Ty> template _NODISCARD constexpr bool _In_range(const _Ty _Value) noexcept { - static_assert(_Is_standard_integer<_Rx> && _Is_standard_integer<_Ty>, - "The integer comparison functions only accept standard and extended integer types."); + _STL_INTERNAL_STATIC_ASSERT(_Is_nonbool_integral<_Rx> && _Is_nonbool_integral<_Ty>); // allows character types constexpr auto _Ty_min = _Min_limit<_Ty>(); constexpr auto _Rx_min = _Min_limit<_Rx>(); @@ -883,38 +881,56 @@ _NODISCARD constexpr bool _In_range(const _Ty _Value) noexcept { } #if _HAS_CXX20 +template +constexpr bool _Is_standard_integer = _Is_any_of_v, signed char, short, int, long, long long, + unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>; + _EXPORT_STD template _NODISCARD constexpr bool cmp_equal(const _Ty1 _Left, const _Ty2 _Right) noexcept { + static_assert(_Is_standard_integer<_Ty1> && _Is_standard_integer<_Ty2>, + "The integer comparison functions only accept standard and extended integer types."); return _STD _Cmp_equal(_Left, _Right); } _EXPORT_STD template _NODISCARD constexpr bool cmp_not_equal(const _Ty1 _Left, const _Ty2 _Right) noexcept { + static_assert(_Is_standard_integer<_Ty1> && _Is_standard_integer<_Ty2>, + "The integer comparison functions only accept standard and extended integer types."); return _STD _Cmp_not_equal(_Left, _Right); } _EXPORT_STD template _NODISCARD constexpr bool cmp_less(const _Ty1 _Left, const _Ty2 _Right) noexcept { + static_assert(_Is_standard_integer<_Ty1> && _Is_standard_integer<_Ty2>, + "The integer comparison functions only accept standard and extended integer types."); return _STD _Cmp_less(_Left, _Right); } _EXPORT_STD template _NODISCARD constexpr bool cmp_greater(const _Ty1 _Left, const _Ty2 _Right) noexcept { + static_assert(_Is_standard_integer<_Ty1> && _Is_standard_integer<_Ty2>, + "The integer comparison functions only accept standard and extended integer types."); return _STD _Cmp_greater(_Left, _Right); } _EXPORT_STD template _NODISCARD constexpr bool cmp_less_equal(const _Ty1 _Left, const _Ty2 _Right) noexcept { + static_assert(_Is_standard_integer<_Ty1> && _Is_standard_integer<_Ty2>, + "The integer comparison functions only accept standard and extended integer types."); return _STD _Cmp_less_equal(_Left, _Right); } _EXPORT_STD template _NODISCARD constexpr bool cmp_greater_equal(const _Ty1 _Left, const _Ty2 _Right) noexcept { + static_assert(_Is_standard_integer<_Ty1> && _Is_standard_integer<_Ty2>, + "The integer comparison functions only accept standard and extended integer types."); return _STD _Cmp_greater_equal(_Left, _Right); } _EXPORT_STD template _NODISCARD constexpr bool in_range(const _Ty _Value) noexcept { + static_assert(_Is_standard_integer<_Rx> && _Is_standard_integer<_Ty>, + "The integer comparison functions only accept standard and extended integer types."); return _STD _In_range<_Rx>(_Value); } #endif // _HAS_CXX20 diff --git a/stl/inc/valarray b/stl/inc/valarray index 79ad50083a1..38303a6419a 100644 --- a/stl/inc/valarray +++ b/stl/inc/valarray @@ -1439,7 +1439,7 @@ public: } #if _HAS_CXX20 - _NODISCARD_FRIEND bool operator==(const slice& _Left, const slice& _Right) noexcept /* strengthened */ { + _NODISCARD friend bool operator==(const slice& _Left, const slice& _Right) noexcept /* strengthened */ { return _Left.start() == _Right.start() && _Left.size() == _Right.size() && _Left.stride() == _Right.stride(); } #endif // _HAS_CXX20 diff --git a/stl/inc/vector b/stl/inc/vector index f6d6cf4302a..bc99da1dc7b 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -136,7 +136,7 @@ public: return _Tmp; } - _NODISCARD_FRIEND _CONSTEXPR20 _Vector_const_iterator operator+( + _NODISCARD friend _CONSTEXPR20 _Vector_const_iterator operator+( const difference_type _Off, _Vector_const_iterator _Next) noexcept { _Next += _Off; return _Next; @@ -316,7 +316,7 @@ public: return _Tmp; } - _NODISCARD_FRIEND _CONSTEXPR20 _Vector_iterator operator+( + _NODISCARD friend _CONSTEXPR20 _Vector_iterator operator+( const difference_type _Off, _Vector_iterator _Next) noexcept { _Next += _Off; return _Next; @@ -2568,7 +2568,7 @@ public: return _Tmp; } - _NODISCARD_FRIEND _CONSTEXPR20 _Vb_const_iterator operator+( + _NODISCARD friend _CONSTEXPR20 _Vb_const_iterator operator+( const difference_type _Off, _Vb_const_iterator _Right) noexcept { _Right += _Off; return _Right; @@ -2741,7 +2741,7 @@ public: return _Tmp; } - _NODISCARD_FRIEND _CONSTEXPR20 _Vb_iterator operator+(const difference_type _Off, _Vb_iterator _Right) noexcept { + _NODISCARD friend _CONSTEXPR20 _Vb_iterator operator+(const difference_type _Off, _Vb_iterator _Right) noexcept { _Right += _Off; return _Right; } diff --git a/stl/inc/xcharconv.h b/stl/inc/xcharconv.h index 07f6c2f8752..7140f489ca1 100644 --- a/stl/inc/xcharconv.h +++ b/stl/inc/xcharconv.h @@ -37,7 +37,7 @@ _EXPORT_STD struct to_chars_result { char* ptr; errc ec; #if _HAS_CXX20 - _NODISCARD_FRIEND bool operator==(const to_chars_result&, const to_chars_result&) = default; + _NODISCARD friend bool operator==(const to_chars_result&, const to_chars_result&) = default; #endif // _HAS_CXX20 }; diff --git a/stl/inc/xhash b/stl/inc/xhash index 664b127fc1e..dfa0cf3f2b8 100644 --- a/stl/inc/xhash +++ b/stl/inc/xhash @@ -199,12 +199,12 @@ struct _Reinterpret_move_iter { // post ++ intentionally omitted - _NODISCARD_FRIEND bool operator==(const _Reinterpret_move_iter& _Lhs, const _Reinterpret_move_iter& _Rhs) { + _NODISCARD friend bool operator==(const _Reinterpret_move_iter& _Lhs, const _Reinterpret_move_iter& _Rhs) { return _Lhs._Base == _Rhs._Base; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=(const _Reinterpret_move_iter& _Lhs, const _Reinterpret_move_iter& _Rhs) { + _NODISCARD friend bool operator!=(const _Reinterpret_move_iter& _Lhs, const _Reinterpret_move_iter& _Rhs) { return _Lhs._Base != _Rhs._Base; } #endif // !_HAS_CXX20 diff --git a/stl/inc/xpolymorphic_allocator.h b/stl/inc/xpolymorphic_allocator.h index 0903ce5863f..ea0825c7c9f 100644 --- a/stl/inc/xpolymorphic_allocator.h +++ b/stl/inc/xpolymorphic_allocator.h @@ -310,13 +310,13 @@ namespace pmr { return _Resource; } - _NODISCARD_FRIEND bool operator==( + _NODISCARD friend bool operator==( const polymorphic_allocator& _Lhs, const polymorphic_allocator& _Rhs) noexcept { return *_Lhs._Resource == *_Rhs._Resource; } #if !_HAS_CXX20 - _NODISCARD_FRIEND bool operator!=( + _NODISCARD friend bool operator!=( const polymorphic_allocator& _Lhs, const polymorphic_allocator& _Rhs) noexcept { return *_Lhs._Resource != *_Rhs._Resource; } diff --git a/stl/inc/xstring b/stl/inc/xstring index ed4026cff2b..7b458d16c5b 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -141,7 +141,7 @@ public: return _Tmp; } - _NODISCARD_FRIEND _CONSTEXPR20 _String_const_iterator operator+( + _NODISCARD friend _CONSTEXPR20 _String_const_iterator operator+( const difference_type _Off, _String_const_iterator _Next) noexcept { _Next += _Off; return _Next; @@ -318,7 +318,7 @@ public: return _Tmp; } - _NODISCARD_FRIEND _CONSTEXPR20 _String_iterator operator+( + _NODISCARD friend _CONSTEXPR20 _String_iterator operator+( const difference_type _Off, _String_iterator _Next) noexcept { _Next += _Off; return _Next; diff --git a/stl/inc/xtree b/stl/inc/xtree index 5b7c60bdbe7..42c10a95341 100644 --- a/stl/inc/xtree +++ b/stl/inc/xtree @@ -433,6 +433,20 @@ public: using _Unchecked_const_iterator = _Tree_unchecked_const_iterator<_Tree_val>; using const_iterator = _Tree_const_iterator<_Tree_val>; + template + struct _NODISCARD _Erase_tree_and_orphan_guard { + _Tree_val* _Val_ptr; + _AllocNode& _Al; + _Nodeptr _New_root; + + _Erase_tree_and_orphan_guard& operator=(const _Erase_tree_and_orphan_guard&) = delete; + ~_Erase_tree_and_orphan_guard() noexcept { + if (_Val_ptr != nullptr) { + _Val_ptr->_Erase_tree_and_orphan(_Al, _New_root); // subtree copy failed, bail out + } + } + }; + _Tree_val() noexcept : _Myhead(), _Mysize(0) {} enum _Redbl { // colors for link to parent @@ -1661,20 +1675,16 @@ protected: _Nodeptr _Newroot = _Scary->_Myhead; // point at nil node if (!_Rootnode->_Isnil) { // copy or move a node, then any subtrees - _Nodeptr _Pnode = _Copy_or_move<_Strat>(_Rootnode->_Myval); - _Pnode->_Parent = _Wherenode; - _Pnode->_Color = _Rootnode->_Color; - if (_Newroot->_Isnil) { - _Newroot = _Pnode; // memorize new root - } + _Newroot = _Copy_or_move<_Strat>(_Rootnode->_Myval); // memorize new root + _Newroot->_Parent = _Wherenode; + _Newroot->_Color = _Rootnode->_Color; + + typename _Scary_val::template _Erase_tree_and_orphan_guard<_Alnode> _Guard{_Scary, _Getal(), _Newroot}; + + _Newroot->_Left = _Copy_nodes<_Strat>(_Rootnode->_Left, _Newroot); + _Newroot->_Right = _Copy_nodes<_Strat>(_Rootnode->_Right, _Newroot); - _TRY_BEGIN - _Pnode->_Left = _Copy_nodes<_Strat>(_Rootnode->_Left, _Pnode); - _Pnode->_Right = _Copy_nodes<_Strat>(_Rootnode->_Right, _Pnode); - _CATCH_ALL - _Scary->_Erase_tree_and_orphan(_Getal(), _Newroot); // subtree copy failed, bail out - _RERAISE; - _CATCH_END + _Guard._Val_ptr = nullptr; } return _Newroot; // return newly constructed tree diff --git a/stl/inc/xutility b/stl/inc/xutility index 988196930f3..fbed6751ec2 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -960,31 +960,28 @@ concept contiguous_iterator = random_access_iterator<_It> // clang-format on _EXPORT_STD template -concept indirectly_unary_invocable = - indirectly_readable<_It> && copy_constructible<_Fn> && invocable<_Fn&, _Indirect_value_t<_It>> - && invocable<_Fn&, iter_reference_t<_It>> && invocable<_Fn&, iter_common_reference_t<_It>> - && common_reference_with>, - invoke_result_t<_Fn&, iter_reference_t<_It>>>; +concept indirectly_unary_invocable = indirectly_readable<_It> && copy_constructible<_Fn> + && invocable<_Fn&, _Indirect_value_t<_It>> && invocable<_Fn&, iter_reference_t<_It>> + && common_reference_with>, + invoke_result_t<_Fn&, iter_reference_t<_It>>>; _EXPORT_STD template concept indirectly_regular_unary_invocable = indirectly_readable<_It> && copy_constructible<_Fn> && regular_invocable<_Fn&, _Indirect_value_t<_It>> - && regular_invocable<_Fn&, iter_reference_t<_It>> && regular_invocable<_Fn&, iter_common_reference_t<_It>> + && regular_invocable<_Fn&, iter_reference_t<_It>> && common_reference_with>, invoke_result_t<_Fn&, iter_reference_t<_It>>>; _EXPORT_STD template -concept indirect_unary_predicate = - indirectly_readable<_It> && copy_constructible<_Fn> && predicate<_Fn&, _Indirect_value_t<_It>> - && predicate<_Fn&, iter_reference_t<_It>> && predicate<_Fn&, iter_common_reference_t<_It>>; +concept indirect_unary_predicate = indirectly_readable<_It> && copy_constructible<_Fn> + && predicate<_Fn&, _Indirect_value_t<_It>> && predicate<_Fn&, iter_reference_t<_It>>; _EXPORT_STD template concept indirect_binary_predicate = indirectly_readable<_It1> && indirectly_readable<_It2> && copy_constructible<_Fn> && predicate<_Fn&, _Indirect_value_t<_It1>, _Indirect_value_t<_It2>> && predicate<_Fn&, _Indirect_value_t<_It1>, iter_reference_t<_It2>> && predicate<_Fn&, iter_reference_t<_It1>, _Indirect_value_t<_It2>> - && predicate<_Fn&, iter_reference_t<_It1>, iter_reference_t<_It2>> - && predicate<_Fn&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; + && predicate<_Fn&, iter_reference_t<_It1>, iter_reference_t<_It2>>; _EXPORT_STD template concept indirect_equivalence_relation = @@ -992,17 +989,14 @@ concept indirect_equivalence_relation = && equivalence_relation<_Fn&, _Indirect_value_t<_It1>, _Indirect_value_t<_It2>> && equivalence_relation<_Fn&, _Indirect_value_t<_It1>, iter_reference_t<_It2>> && equivalence_relation<_Fn&, iter_reference_t<_It1>, _Indirect_value_t<_It2>> - && equivalence_relation<_Fn&, iter_reference_t<_It1>, iter_reference_t<_It2>> - && equivalence_relation<_Fn&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; + && equivalence_relation<_Fn&, iter_reference_t<_It1>, iter_reference_t<_It2>>; _EXPORT_STD template -concept indirect_strict_weak_order = - indirectly_readable<_It1> && indirectly_readable<_It2> && copy_constructible<_Fn> - && strict_weak_order<_Fn&, _Indirect_value_t<_It1>, _Indirect_value_t<_It2>> - && strict_weak_order<_Fn&, _Indirect_value_t<_It1>, iter_reference_t<_It2>> - && strict_weak_order<_Fn&, iter_reference_t<_It1>, _Indirect_value_t<_It2>> - && strict_weak_order<_Fn&, iter_reference_t<_It1>, iter_reference_t<_It2>> - && strict_weak_order<_Fn&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; +concept indirect_strict_weak_order = indirectly_readable<_It1> && indirectly_readable<_It2> && copy_constructible<_Fn> + && strict_weak_order<_Fn&, _Indirect_value_t<_It1>, _Indirect_value_t<_It2>> + && strict_weak_order<_Fn&, _Indirect_value_t<_It1>, iter_reference_t<_It2>> + && strict_weak_order<_Fn&, iter_reference_t<_It1>, _Indirect_value_t<_It2>> + && strict_weak_order<_Fn&, iter_reference_t<_It1>, iter_reference_t<_It2>>; _EXPORT_STD template requires (indirectly_readable<_Its> && ...) && invocable<_Fn, iter_reference_t<_Its>...> @@ -1783,7 +1777,7 @@ public: } #if _HAS_CXX20 - _NODISCARD_FRIEND constexpr iter_rvalue_reference_t<_BidIt> iter_move(const reverse_iterator& _It) noexcept( + _NODISCARD friend constexpr iter_rvalue_reference_t<_BidIt> iter_move(const reverse_iterator& _It) noexcept( is_nothrow_copy_constructible_v<_BidIt> // && noexcept(_RANGES iter_move(--_STD declval<_BidIt&>()))) { auto _Tmp = _It.current; @@ -2386,47 +2380,47 @@ public: template <_Not_a_const_iterator _Other> requires random_access_iterator<_Iter> && totally_ordered_with<_Iter, _Other> - _NODISCARD_FRIEND constexpr bool operator<(const _Other& _Left, const basic_const_iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<(const _Other& _Left, const basic_const_iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Left < _Right._Current))) /* strengthened */ { return _Left < _Right._Current; } template <_Not_a_const_iterator _Other> requires random_access_iterator<_Iter> && totally_ordered_with<_Iter, _Other> - _NODISCARD_FRIEND constexpr bool operator>(const _Other& _Left, const basic_const_iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>(const _Other& _Left, const basic_const_iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Left > _Right._Current))) /* strengthened */ { return _Left > _Right._Current; } template <_Not_a_const_iterator _Other> requires random_access_iterator<_Iter> && totally_ordered_with<_Iter, _Other> - _NODISCARD_FRIEND constexpr bool operator<=(const _Other& _Left, const basic_const_iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator<=(const _Other& _Left, const basic_const_iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Left <= _Right._Current))) /* strengthened */ { return _Left <= _Right._Current; } template <_Not_a_const_iterator _Other> requires random_access_iterator<_Iter> && totally_ordered_with<_Iter, _Other> - _NODISCARD_FRIEND constexpr bool operator>=(const _Other& _Left, const basic_const_iterator& _Right) noexcept( + _NODISCARD friend constexpr bool operator>=(const _Other& _Left, const basic_const_iterator& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Left >= _Right._Current))) /* strengthened */ { return _Left >= _Right._Current; } - _NODISCARD_FRIEND constexpr basic_const_iterator operator+(const basic_const_iterator& _It, + _NODISCARD friend constexpr basic_const_iterator operator+(const basic_const_iterator& _It, const difference_type _Off) noexcept(noexcept(basic_const_iterator{_It._Current + _Off})) // strengthened requires random_access_iterator<_Iter> { return basic_const_iterator{_It._Current + _Off}; } - _NODISCARD_FRIEND constexpr basic_const_iterator operator+(const difference_type _Off, + _NODISCARD friend constexpr basic_const_iterator operator+(const difference_type _Off, const basic_const_iterator& _It) noexcept(noexcept(basic_const_iterator{_It._Current + _Off})) // strengthened requires random_access_iterator<_Iter> { return basic_const_iterator{_It._Current + _Off}; } - _NODISCARD_FRIEND constexpr basic_const_iterator operator-(const basic_const_iterator& _It, + _NODISCARD friend constexpr basic_const_iterator operator-(const basic_const_iterator& _It, const difference_type _Off) noexcept(noexcept(basic_const_iterator{_It._Current - _Off})) // strengthened requires random_access_iterator<_Iter> { @@ -2441,12 +2435,12 @@ public: template <_Not_a_const_iterator _Sent> requires sized_sentinel_for<_Sent, _Iter> - _NODISCARD_FRIEND constexpr difference_type operator-(const _Sent& _Se, const basic_const_iterator& _It) noexcept( + _NODISCARD friend constexpr difference_type operator-(const _Sent& _Se, const basic_const_iterator& _It) noexcept( noexcept(_Se - _It._Current)) /* strengthened */ { return _Se - _It._Current; } - _NODISCARD_FRIEND constexpr _Rvalue_reference iter_move(const basic_const_iterator& _It) noexcept( + _NODISCARD friend constexpr _Rvalue_reference iter_move(const basic_const_iterator& _It) noexcept( noexcept(static_cast<_Rvalue_reference>(_RANGES iter_move(_It._Current)))) { return static_cast<_Rvalue_reference>(_RANGES iter_move(_It._Current)); } @@ -4313,25 +4307,25 @@ public: #if _HAS_CXX20 template _Sent> - _NODISCARD_FRIEND constexpr bool + _NODISCARD friend constexpr bool operator==(const move_iterator& _Left, const move_sentinel<_Sent>& _Right) noexcept( noexcept(_STD _Fake_copy_init(_Left._Current == _Right._Get_last()))) /* strengthened */ { return _Left._Current == _Right._Get_last(); } template _Sent> - _NODISCARD_FRIEND constexpr difference_type operator-(const move_sentinel<_Sent>& _Left, + _NODISCARD friend constexpr difference_type operator-(const move_sentinel<_Sent>& _Left, const move_iterator& _Right) noexcept(noexcept(_Left._Get_last() - _Right._Current)) /* strengthened */ { return _Left._Get_last() - _Right._Current; } template _Sent> - _NODISCARD_FRIEND constexpr difference_type operator-(const move_iterator& _Left, + _NODISCARD friend constexpr difference_type operator-(const move_iterator& _Left, const move_sentinel<_Sent>& _Right) noexcept(noexcept(_Left._Current - _Right._Get_last())) /* strengthened */ { return _Left._Current - _Right._Get_last(); } - _NODISCARD_FRIEND constexpr reference iter_move(const move_iterator& _It) noexcept( + _NODISCARD friend constexpr reference iter_move(const move_iterator& _It) noexcept( noexcept(_RANGES iter_move(_It._Current))) { return _RANGES iter_move(_It._Current); } @@ -4500,7 +4494,7 @@ _EXPORT_STD struct unreachable_sentinel_t; namespace _Unreachable_sentinel_detail { struct _Base { template - _NODISCARD_FRIEND constexpr bool operator==(const unreachable_sentinel_t&, const _Winc&) noexcept { + _NODISCARD friend constexpr bool operator==(const unreachable_sentinel_t&, const _Winc&) noexcept { return false; } }; @@ -5381,15 +5375,6 @@ template constexpr bool _Equal_memcmp_is_safe = _Equal_memcmp_is_safe_helper, remove_const_t<_Iter2>, remove_const_t<_Pr>>; -template -_NODISCARD int _Memcmp_ranges(_CtgIt1 _First1, _CtgIt1 _Last1, _CtgIt2 _First2) { - _STL_INTERNAL_STATIC_ASSERT(sizeof(_Iter_value_t<_CtgIt1>) == sizeof(_Iter_value_t<_CtgIt2>)); - const auto _First1_ch = reinterpret_cast(_STD _To_address(_First1)); - const auto _Last1_ch = reinterpret_cast(_STD _To_address(_Last1)); - const auto _First2_ch = reinterpret_cast(_STD _To_address(_First2)); - return _CSTD memcmp(_First1_ch, _First2_ch, static_cast(_Last1_ch - _First1_ch)); -} - template _NODISCARD int _Memcmp_count(_CtgIt1 _First1, _CtgIt2 _First2, const size_t _Count) { _STL_INTERNAL_STATIC_ASSERT(sizeof(_Iter_value_t<_CtgIt1>) == sizeof(_Iter_value_t<_CtgIt2>)); @@ -5410,7 +5395,11 @@ _NODISCARD _CONSTEXPR20 bool equal(const _InIt1 _First1, const _InIt1 _Last1, co if (!_STD is_constant_evaluated()) #endif // _HAS_CXX20 { - return _STD _Memcmp_ranges(_UFirst1, _ULast1, _UFirst2) == 0; + _STL_INTERNAL_STATIC_ASSERT( + sizeof(_Iter_value_t) == sizeof(_Iter_value_t)); + const auto _First1_ch = reinterpret_cast(_STD _To_address(_UFirst1)); + const auto _Size = reinterpret_cast(_STD _To_address(_ULast1)) - _First1_ch; + return _CSTD memcmp(_First1_ch, _STD _To_address(_UFirst2), static_cast(_Size)) == 0; } } @@ -7010,7 +6999,7 @@ namespace ranges { } } #endif // _USE_STD_VECTOR_ALGORITHMS - if constexpr (forward_range<_Rng> && _Prefer_iterator_copies>) { + if constexpr (forward_range<_Rng> && _Prefer_iterator_copies) { return static_cast>(*_RANGES _Max_element_unchecked( _STD move(_UFirst), _STD move(_ULast), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj))); } else { @@ -7228,7 +7217,7 @@ namespace ranges { } } #endif // _USE_STD_VECTOR_ALGORITHMS - if constexpr (forward_range<_Rng> && _Prefer_iterator_copies>) { + if constexpr (forward_range<_Rng> && _Prefer_iterator_copies) { return static_cast>(*_RANGES _Min_element_unchecked( _STD move(_UFirst), _STD move(_ULast), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj))); } else { @@ -7372,16 +7361,25 @@ _NODISCARD constexpr bool _Add_overflow(const _Int _Left, const _Int _Right, _In } } } +#endif // _HAS_CXX23 +#if _HAS_CXX17 +#if _HAS_CXX20 template <_Integer_like _Int> +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv +template , int> = 0> +#endif // ^^^ !_HAS_CXX20 ^^^ _NODISCARD constexpr bool _Mul_overflow(const _Int _Left, const _Int _Right, _Int& _Out) { +#if defined(__clang__) && !_HAS_CXX20 + return __builtin_mul_overflow(_Left, _Right, &_Out); +#else // ^^^ defined(__clang__) && !_HAS_CXX20 / !defined(__clang__) || _HAS_CXX20 vvv #ifdef __clang__ - if constexpr (integral<_Int>) { + if constexpr (is_integral_v<_Int>) { return __builtin_mul_overflow(_Left, _Right, &_Out); } else #endif // defined(__clang__) { - if constexpr (!_Signed_integer_like<_Int>) { + if constexpr (static_cast<_Int>(-1) > static_cast<_Int>(0)) { constexpr auto _UInt_max = _STD _Max_limit<_Int>(); const bool _Overflow = _Left != 0 && _Right > _UInt_max / _Left; if (!_Overflow) { @@ -7420,8 +7418,9 @@ _NODISCARD constexpr bool _Mul_overflow(const _Int _Left, const _Int _Right, _In // ^^^ Based on llvm::MulOverflow ^^^ } } +#endif // ^^^ !defined(__clang__) || _HAS_CXX20 ^^^ } -#endif // _HAS_CXX23 +#endif // _HAS_CXX17 _STD_END diff --git a/stl/inc/yvals.h b/stl/inc/yvals.h index d2201390f57..33ac7c51203 100644 --- a/stl/inc/yvals.h +++ b/stl/inc/yvals.h @@ -315,22 +315,6 @@ _EMIT_STL_WARNING(STL4001, "/clr:pure is deprecated and will be REMOVED."); #define _LOCK_STREAM 2 #define _LOCK_DEBUG 3 -#ifndef _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B -#if _STL_WIN32_WINNT >= _STL_WIN32_WINNT_WINBLUE && defined(_WIN64) -#define _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B 1 -#else // ^^^ modern 64-bit / less modern or 32-bit vvv -#define _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B 0 -#endif // _STL_WIN32_WINNT >= _STL_WIN32_WINNT_WINBLUE && defined(_WIN64) -#endif // !defined(_STD_ATOMIC_ALWAYS_USE_CMPXCHG16B) - -#if _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 0 && defined(_M_ARM64) -#error ARM64 requires _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B to be 1. -#endif // _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 0 && defined(_M_ARM64) - -#if _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 1 && !defined(_WIN64) -#error _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 1 requires 64-bit. -#endif // _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 1 && !defined(_WIN64) - _STD_BEGIN enum _Uninitialized { // tag for suppressing initialization _Noinit diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index e20782e6f87..9d8c99da832 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -79,6 +79,7 @@ // P2407R5 Freestanding Library: Partial Classes // (__cpp_lib_freestanding_algorithm and __cpp_lib_freestanding_array only) // P2937R0 Freestanding Library: Remove strtok +// P2968R2 Make std::ignore A First-Class Object // _HAS_CXX17 directly controls: // P0005R4 not_fn() @@ -312,6 +313,7 @@ // P2770R0 Stashing Stashing Iterators For Proper Flattening // P2905R2 Runtime Format Strings // P2909R4 Fix Formatting Of Code Units As Integers +// P2997R1 Removing The Common Reference Requirement From The Indirectly Invocable Concepts // _HAS_CXX20 indirectly controls: // P0619R4 Removing C++17-Deprecated Features @@ -592,12 +594,6 @@ #define _NODISCARD_CTOR_MSG(_Msg) #endif // ^^^ defined(__has_cpp_attribute) && __has_cpp_attribute(nodiscard) < 201907L ^^^ -#if defined(__CUDACC__) && !defined(__clang__) // TRANSITION, VSO-568006 -#define _NODISCARD_FRIEND friend -#else // ^^^ workaround / no workaround vvv -#define _NODISCARD_FRIEND _NODISCARD friend -#endif // ^^^ no workaround ^^^ - #define _NODISCARD_REMOVE_ALG \ _NODISCARD_MSG("The 'remove' and 'remove_if' algorithms return the iterator past the last element " \ "that should be kept. You need to call container.erase(result, container.end()) afterwards. " \ @@ -889,7 +885,7 @@ #define _CPPLIB_VER 650 #define _MSVC_STL_VERSION 143 -#define _MSVC_STL_UPDATE 202406L +#define _MSVC_STL_UPDATE 202407L #ifndef _ALLOW_COMPILER_AND_STL_VERSION_MISMATCH #if defined(__CUDACC__) && defined(__CUDACC_VER_MAJOR__) @@ -903,8 +899,8 @@ _EMIT_STL_ERROR(STL1002, "Unexpected compiler version, expected CUDA 12.4 or new _EMIT_STL_ERROR(STL1000, "Unexpected compiler version, expected Clang 17.0.0 or newer."); #endif // ^^^ old Clang ^^^ #elif defined(_MSC_VER) -#if _MSC_VER < 1940 // Coarse-grained, not inspecting _MSC_FULL_VER -_EMIT_STL_ERROR(STL1001, "Unexpected compiler version, expected MSVC 19.40 or newer."); +#if _MSC_VER < 1941 // Coarse-grained, not inspecting _MSC_FULL_VER +_EMIT_STL_ERROR(STL1001, "Unexpected compiler version, expected MSVC 19.41 or newer."); #endif // ^^^ old MSVC ^^^ #else // vvv other compilers vvv // not attempting to detect other compilers @@ -1844,7 +1840,8 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #endif #if _HAS_CXX23 -#define __cpp_lib_ranges 202302L // P2609R3 Relaxing Ranges Just A Smidge +// P2997R1 Removing The Common Reference Requirement From The Indirectly Invocable Concepts +#define __cpp_lib_ranges 202406L #elif _HAS_CXX20 #define __cpp_lib_ranges 202110L // P2415R2 What Is A view? #endif @@ -1943,10 +1940,9 @@ compiler option, or define _ALLOW_RTCc_IN_STL to suppress this error. #error In yvals_core.h, defined(MRTDLL) implies defined(_M_CEE_PURE); !defined(_M_CEE_PURE) implies !defined(MRTDLL) #endif // defined(MRTDLL) && !defined(_M_CEE_PURE) -#define _STL_WIN32_WINNT_VISTA 0x0600 // _WIN32_WINNT_VISTA from sdkddkver.h -#define _STL_WIN32_WINNT_WIN8 0x0602 // _WIN32_WINNT_WIN8 from sdkddkver.h -#define _STL_WIN32_WINNT_WINBLUE 0x0603 // _WIN32_WINNT_WINBLUE from sdkddkver.h -#define _STL_WIN32_WINNT_WIN10 0x0A00 // _WIN32_WINNT_WIN10 from sdkddkver.h +#define _STL_WIN32_WINNT_VISTA 0x0600 // _WIN32_WINNT_VISTA from sdkddkver.h +#define _STL_WIN32_WINNT_WIN8 0x0602 // _WIN32_WINNT_WIN8 from sdkddkver.h +#define _STL_WIN32_WINNT_WIN10 0x0A00 // _WIN32_WINNT_WIN10 from sdkddkver.h // Note that the STL DLL builds will set this to XP for ABI compatibility with VS2015 which supported XP. #ifndef _STL_WIN32_WINNT diff --git a/stl/src/atomic_wait.cpp b/stl/src/atomic_wait.cpp index b9d907150ba..4bafb1a86bb 100644 --- a/stl/src/atomic_wait.cpp +++ b/stl/src/atomic_wait.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -90,24 +91,6 @@ namespace { } #endif // defined(_DEBUG) } - - [[nodiscard]] unsigned char __std_atomic_compare_exchange_128_fallback( - _Inout_bytecount_(16) long long* _Destination, _In_ long long _ExchangeHigh, _In_ long long _ExchangeLow, - _Inout_bytecount_(16) long long* _ComparandResult) noexcept { - static SRWLOCK _Mtx = SRWLOCK_INIT; - _SrwLock_guard _Guard{_Mtx}; - if (_Destination[0] == _ComparandResult[0] && _Destination[1] == _ComparandResult[1]) { - _ComparandResult[0] = _Destination[0]; - _ComparandResult[1] = _Destination[1]; - _Destination[0] = _ExchangeLow; - _Destination[1] = _ExchangeHigh; - return static_cast(true); - } else { - _ComparandResult[0] = _Destination[0]; - _ComparandResult[1] = _Destination[1]; - return static_cast(false); - } - } } // unnamed namespace extern "C" { @@ -249,41 +232,27 @@ _Smtx_t* __stdcall __std_atomic_get_mutex(const void* const _Key) noexcept { } #pragma warning(pop) +// TRANSITION, ABI: preserved for binary compatibility [[nodiscard]] unsigned char __stdcall __std_atomic_compare_exchange_128(_Inout_bytecount_(16) long long* _Destination, _In_ long long _ExchangeHigh, _In_ long long _ExchangeLow, _Inout_bytecount_(16) long long* _ComparandResult) noexcept { -#if !defined(_WIN64) - return __std_atomic_compare_exchange_128_fallback(_Destination, _ExchangeHigh, _ExchangeLow, _ComparandResult); -#elif _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 1 +#ifdef _WIN64 return _InterlockedCompareExchange128(_Destination, _ExchangeHigh, _ExchangeLow, _ComparandResult); -#else // ^^^ _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 1 / _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 0 vvv - if (__std_atomic_has_cmpxchg16b()) { - return _InterlockedCompareExchange128(_Destination, _ExchangeHigh, _ExchangeLow, _ComparandResult); - } - - return __std_atomic_compare_exchange_128_fallback(_Destination, _ExchangeHigh, _ExchangeLow, _ComparandResult); -#endif // ^^^ _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 0 ^^^ +#else // ^^^ 64-bit / 32-bit vvv + (void) _Destination; + (void) _ExchangeHigh; + (void) _ExchangeLow; + (void) _ComparandResult; + _CSTD abort(); +#endif // ^^^ 32-bit ^^^ } +// TRANSITION, ABI: preserved for binary compatibility [[nodiscard]] char __stdcall __std_atomic_has_cmpxchg16b() noexcept { -#if !defined(_WIN64) - return false; -#elif _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 1 +#ifdef _WIN64 return true; -#else // ^^^ _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 1 / _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 0 vvv - constexpr char _Cmpxchg_Absent = 0; - constexpr char _Cmpxchg_Present = 1; - constexpr char _Cmpxchg_Unknown = 2; - - static std::atomic _Cached_value{_Cmpxchg_Unknown}; - - char _Value = _Cached_value.load(std::memory_order_relaxed); - if (_Value == _Cmpxchg_Unknown) { - _Value = IsProcessorFeaturePresent(PF_COMPARE_EXCHANGE128) ? _Cmpxchg_Present : _Cmpxchg_Absent; - _Cached_value.store(_Value, std::memory_order_relaxed); - } - - return _Value; -#endif // ^^^ _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 0 ^^^ +#else + _CSTD abort(); +#endif } } // extern "C" diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index d7b14591956..5ae8f27917d 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -123,6 +123,14 @@ 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 P2997R1: "Removing The Common Reference Requirement From The Indirectly Invocable Concepts" +std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp FAIL +std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp FAIL +std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp FAIL +std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp FAIL +std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp FAIL +std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.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 @@ -168,6 +176,13 @@ std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitiali std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.default.pass.cpp FAIL std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.iter.pass.cpp FAIL +# libc++ doesn't implement LWG-4061 +std/utilities/format/format.functions/bug_81590.compile.pass.cpp FAIL + +# libc++ doesn't implement LWG-4106 +std/utilities/format/format.arguments/format.args/ctor.pass.cpp FAIL +std/utilities/format/format.arguments/format.args/get.pass.cpp FAIL + # If any feature-test macro test is failing, this consolidated test will also fail. std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp FAIL diff --git a/tests/std/tests/P0019R8_atomic_ref/env.lst b/tests/std/tests/P0019R8_atomic_ref/env.lst index b3f3ea48644..351a8293d9d 100644 --- a/tests/std/tests/P0019R8_atomic_ref/env.lst +++ b/tests/std/tests/P0019R8_atomic_ref/env.lst @@ -2,6 +2,3 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception RUNALL_INCLUDE ..\usual_20_matrix.lst -RUNALL_CROSSLIST -* PM_CL="" -* PM_CL="/D_STD_ATOMIC_ALWAYS_USE_CMPXCHG16B=1 /DTEST_CMPXCHG16B" diff --git a/tests/std/tests/P0019R8_atomic_ref/test.cpp b/tests/std/tests/P0019R8_atomic_ref/test.cpp index 6cdfd4518ad..8edf08cfd9e 100644 --- a/tests/std/tests/P0019R8_atomic_ref/test.cpp +++ b/tests/std/tests/P0019R8_atomic_ref/test.cpp @@ -1,12 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#if defined(TEST_CMPXCHG16B) && (defined(__clang__) || !defined(_M_X64)) -// Skip Clang because it would require the -mcx16 compiler option. -// Skip non-x64 because _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B is always 1 for ARM64, and is forbidden to be 1 for 32-bit. -int main() {} -#else // ^^^ skip test / run test vvv - #include #include #include @@ -436,13 +430,8 @@ void test_gh_4472() { static_assert(std::atomic_ref::required_alignment == sizeof(two_pointers_t)); -#ifdef _WIN64 - static_assert(std::atomic_ref::is_always_lock_free == _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B); -#else static_assert(std::atomic_ref::is_always_lock_free); -#endif - // We expect tests to run on machines that support DCAS, which is required by Win8+. std::atomic_ref ar{two_pointers}; assert(ar.is_lock_free()); } @@ -518,5 +507,3 @@ int main() { test_gh_4472(); test_gh_4728(); } - -#endif // ^^^ run test ^^^ diff --git a/tests/std/tests/P0295R0_gcd_lcm/test.compile.pass.cpp b/tests/std/tests/P0295R0_gcd_lcm/test.compile.pass.cpp index 03f56a523dd..58ac9095bfc 100644 --- a/tests/std/tests/P0295R0_gcd_lcm/test.compile.pass.cpp +++ b/tests/std/tests/P0295R0_gcd_lcm/test.compile.pass.cpp @@ -36,7 +36,7 @@ static_assert(gcd(1073741824, 536870912) == 536870912); static_assert(gcd(1073741824, -536870912) == 536870912); static_assert(gcd(-1073741824, 536870912) == 536870912); static_assert(gcd(int_max, int_max) == int_max); -static_assert(gcd(int_min, int_max) == 1); +// gcd(int_min, int_max) -> undefined behavior // gcd(int_min, int_min) -> undefined behavior static_assert(gcd(int_min + 1, int_min + 1) == int_max); @@ -49,3 +49,28 @@ static_assert(lcm(1, 0) == 0); static_assert(lcm(1073741824, 536870912) == 1073741824); static_assert(lcm(1073741824, -536870912) == 1073741824); static_assert(lcm(-1073741824, 536870912) == 1073741824); + +template +constexpr bool test_nonbool_integral_type() { + static_assert(gcd(T{60}, T{24}) == T{12}); + static_assert(lcm(T{60}, T{24}) == T{120}); + return true; +} + +static_assert(test_nonbool_integral_type()); +static_assert(test_nonbool_integral_type()); +#ifdef __cpp_char8_t +static_assert(test_nonbool_integral_type()); +#endif // __cpp_char8_t +static_assert(test_nonbool_integral_type()); +static_assert(test_nonbool_integral_type()); +static_assert(test_nonbool_integral_type()); +static_assert(test_nonbool_integral_type()); +static_assert(test_nonbool_integral_type()); +static_assert(test_nonbool_integral_type()); +static_assert(test_nonbool_integral_type()); +static_assert(test_nonbool_integral_type()); +static_assert(test_nonbool_integral_type()); +static_assert(test_nonbool_integral_type()); +static_assert(test_nonbool_integral_type()); +static_assert(test_nonbool_integral_type()); diff --git a/tests/std/tests/P0645R10_text_formatting_custom_formatting/test.cpp b/tests/std/tests/P0645R10_text_formatting_custom_formatting/test.cpp index 6a9db58b132..5c2c17327e5 100644 --- a/tests/std/tests/P0645R10_text_formatting_custom_formatting/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_custom_formatting/test.cpp @@ -266,8 +266,13 @@ void test_basic_format_context_construction() { using context = basic_format_context; static_assert(!is_default_constructible_v); - static_assert(is_copy_constructible_v == is_copy_constructible_v); - static_assert(is_move_constructible_v); + static_assert(!is_copy_constructible_v); + static_assert(!is_move_constructible_v); + + // Also test the deleted copy assignment operator + // from LWG-4061 "Should std::basic_format_context be default-constructible/copyable/movable?" + static_assert(!is_copy_assignable_v); + static_assert(!is_move_assignable_v); static_assert(!is_constructible_v>); static_assert(!is_constructible_v&>); @@ -275,6 +280,9 @@ void test_basic_format_context_construction() { static_assert(!is_constructible_with_trailing_empty_brace_impl); static_assert(!is_constructible_with_trailing_empty_brace_impl>); static_assert(!is_constructible_with_trailing_empty_brace_impl&>); + + // Also test LWG-4106 "basic_format_args should not be default-constructible" + static_assert(!is_default_constructible_v>); } // Test GH-4636 ": Call to next_arg_id may result in unexpected error (regression)" diff --git a/tests/std/tests/P0896R4_ranges_algorithm_machinery/test.compile.pass.cpp b/tests/std/tests/P0896R4_ranges_algorithm_machinery/test.compile.pass.cpp index 3f3502bc15d..aa272fea61b 100644 --- a/tests/std/tests/P0896R4_ranges_algorithm_machinery/test.compile.pass.cpp +++ b/tests/std/tests/P0896R4_ranges_algorithm_machinery/test.compile.pass.cpp @@ -79,6 +79,8 @@ namespace indirectly_unary_invocable_test { // 2: not invocable> void operator()(simple_reference) const requires (I == 2) = delete; // 3: not invocable> + // This case is made valid by P2997R1 + // "Removing The Common Reference Requirement From The Indirectly Invocable Concepts". void operator()(simple_common_reference) const requires (I == 3) = delete; // 4 : not common_reference_with&>, @@ -101,7 +103,7 @@ namespace indirectly_unary_invocable_test { static_assert(!test, simple_iter_archetype<1>>()); static_assert(!test, simple_iter_archetype<1>>()); static_assert(!test, simple_iter_archetype<1>>()); - static_assert(!test, simple_iter_archetype<1>>()); + static_assert(test, simple_iter_archetype<1>>()); static_assert(!test, simple_iter_archetype<1>>()); static_assert(!test, simple_iter_archetype<0>>()); static_assert(test, simple_iter_archetype<1>>()); @@ -130,6 +132,8 @@ namespace indirect_unary_predicate_test { // 2: not predicate> void operator()(simple_reference) const requires (I == 2) = delete; // 3: not predicate> + // This case is made valid by P2997R1 + // "Removing The Common Reference Requirement From The Indirectly Invocable Concepts". void operator()(simple_common_reference) const requires (I == 3) = delete; // 4: all of the above @@ -142,7 +146,7 @@ namespace indirect_unary_predicate_test { static_assert(!indirect_unary_predicate, simple_iter_archetype<1>>); static_assert(!indirect_unary_predicate, simple_iter_archetype<1>>); static_assert(!indirect_unary_predicate, simple_iter_archetype<1>>); - static_assert(!indirect_unary_predicate, simple_iter_archetype<1>>); + static_assert(indirect_unary_predicate, simple_iter_archetype<1>>); static_assert(!indirect_unary_predicate, simple_iter_archetype<1>>); static_assert(!indirect_unary_predicate, simple_iter_archetype<0>>); static_assert(indirect_unary_predicate, simple_iter_archetype<1>>); @@ -174,6 +178,8 @@ namespace indirect_binary_predicate_test { // 4: not predicate, iter_reference_t> void operator()(simple_reference, simple_reference) const requires (I == 4); // 5: not predicate, iter_common_reference_t> + // This case is made valid by P2997R1 + // "Removing The Common Reference Requirement From The Indirectly Invocable Concepts". void operator()(simple_common_reference, simple_common_reference) const requires (I == 5); bool operator()(int&, int&) const requires (I != 1); @@ -202,7 +208,7 @@ namespace indirect_binary_predicate_test { static_assert(!test<2, 1, 1>()); static_assert(!test<3, 1, 1>()); static_assert(!test<4, 1, 1>()); - static_assert(!test<5, 1, 1>()); + static_assert(test<5, 1, 1>()); static_assert(!test<6, 0, 1>()); static_assert(!test<6, 1, 0>()); diff --git a/tests/std/tests/P0896R4_views_iota/test.cpp b/tests/std/tests/P0896R4_views_iota/test.cpp index 3e9e21759bb..ef55a94ee04 100644 --- a/tests/std/tests/P0896R4_views_iota/test.cpp +++ b/tests/std/tests/P0896R4_views_iota/test.cpp @@ -19,6 +19,9 @@ static_assert(ranges::_Advanceable); template concept CanViewIota = requires(W w, B b) { views::iota(w, b); }; +template +concept CanUnaryViewsIota = requires(W&& w) { views::iota(forward(w)); }; + template concept CanSize = requires(R& r) { ranges::size(r); }; @@ -333,6 +336,18 @@ constexpr bool test_gh_3025() { return true; } +// LWG-4096 "views::iota(views::iota(0)) should be rejected" +static_assert(CanUnaryViewsIota); +static_assert(CanUnaryViewsIota); +static_assert(CanUnaryViewsIota>>); +static_assert(!CanUnaryViewsIota>); +static_assert(!CanUnaryViewsIota>); +static_assert(!CanUnaryViewsIota>>>); +static_assert(!CanUnaryViewsIota>); +static_assert(!CanUnaryViewsIota>); +static_assert(!CanUnaryViewsIota>, + ranges::iterator_t>>>); + int main() { // Validate standard signed integer types static_assert((test_integral(), true)); diff --git a/tests/std/tests/P2286R8_text_formatting_formattable/test.compile.pass.cpp b/tests/std/tests/P2286R8_text_formatting_formattable/test.compile.pass.cpp index 3dd6fa18038..5ffea68fa60 100644 --- a/tests/std/tests/P2286R8_text_formatting_formattable/test.compile.pass.cpp +++ b/tests/std/tests/P2286R8_text_formatting_formattable/test.compile.pass.cpp @@ -269,7 +269,11 @@ enum class ec { a }; template void test_disabled() { if constexpr (!same_as) { + assert_is_not_formattable(); assert_is_not_formattable(); + assert_is_not_formattable(); + assert_is_not_formattable(); + assert_is_not_formattable(); } assert_is_not_formattable(); diff --git a/tests/std/tests/P2321R2_views_adjacent/test.cpp b/tests/std/tests/P2321R2_views_adjacent/test.cpp index 55e67707f11..ac0647a0873 100644 --- a/tests/std/tests/P2321R2_views_adjacent/test.cpp +++ b/tests/std/tests/P2321R2_views_adjacent/test.cpp @@ -43,7 +43,7 @@ static_assert(same_as, tuple>); // Check views::pairwise static_assert(same_as)>); -template +template constexpr bool test_one(Rng&& rng, Expected&& expected) { using ranges::adjacent_view, ranges::forward_range, ranges::bidirectional_range, ranges::random_access_range, ranges::sized_range, ranges::common_range, ranges::iterator_t, ranges::sentinel_t, ranges::const_iterator_t, @@ -55,7 +55,6 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) { using R = adjacent_view; static_assert(ranges::view); - static_assert(ranges::input_range); static_assert(forward_range); static_assert(bidirectional_range == bidirectional_range); static_assert(random_access_range == random_access_range); @@ -732,7 +731,7 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) { return true; } -template +template constexpr void test_adjacent0(Rng&& rng) { static_assert(!CanConstructAdjacentView); using V = views::all_t; @@ -783,7 +782,7 @@ constexpr void test_adjacent0(Rng&& rng) { } } -template +template requires indirectly_swappable> constexpr void test_iter_swap(Rng& rng) { // This test assumes that 'ranges::size(views::adjacent(rng))' is at least 2 @@ -841,7 +840,7 @@ using test_range = struct instantiator { #ifdef TEST_EVERYTHING - template + template static constexpr void call() { R r{some_ints}; test_one<1>(r, adjacent1_result); @@ -899,6 +898,62 @@ constexpr void instantiation_test() { #endif // TEST_EVERYTHING } +// LWG-4098 views::adjacent<0> should reject non-forward ranges +template +constexpr void test_input_only(Rng&&) { + if constexpr (!ranges::forward_range) { + static_assert(!CanViewAdjacent); + static_assert(!CanViewAdjacent); + static_assert(!CanConstructAdjacentView); + static_assert(!CanConstructAdjacentView); + } + + if constexpr (!ranges::forward_range) { + static_assert(!CanViewAdjacent); + static_assert(!CanViewAdjacent); + static_assert(!CanConstructAdjacentView); + static_assert(!CanConstructAdjacentView); + } +} + +struct input_only_instantiator { +#ifdef TEST_EVERYTHING + template + static constexpr void call() { + R r{some_ints}; + test_input_only<0>(r); + test_input_only<1>(r); + test_input_only<2>(r); + test_input_only<4>(r); + test_input_only<7>(r); + } +#else // ^^^ test all input range permutations / test only "interesting" permutations vvv + template + static constexpr void call() { + test_range r{some_ints}; + test_input_only<0>(r); + test_input_only<1>(r); + test_input_only<2>(r); + test_input_only<4>(r); + test_input_only<7>(r); + } +#endif // TEST_EVERYTHING +}; + +constexpr void instantiation_input_only_test() { +#ifdef TEST_EVERYTHING + test_in(); +#else // ^^^ test all input range permutations / test only "interesting" permutations vvv + using test::Common, test::Sized; + + // The view is sensitive to category, commonality, and size, but oblivious to proxyness and differencing + input_only_instantiator::call(); + input_only_instantiator::call(); + input_only_instantiator::call(); + input_only_instantiator::call(); +#endif // TEST_EVERYTHING +} + template > using move_only_view = test::range}, @@ -939,4 +994,7 @@ int main() { static_assert((instantiation_test(), true)); instantiation_test(); + + static_assert((instantiation_input_only_test(), true)); + instantiation_input_only_test(); } diff --git a/tests/std/tests/P2321R2_views_adjacent_transform/test.cpp b/tests/std/tests/P2321R2_views_adjacent_transform/test.cpp index e9a51c59d89..3c78fd8ee59 100644 --- a/tests/std/tests/P2321R2_views_adjacent_transform/test.cpp +++ b/tests/std/tests/P2321R2_views_adjacent_transform/test.cpp @@ -73,7 +73,7 @@ using invoke_result_with_repeated_type = invoke_result_with_repeated_type_impl, int, 2>, int>); static_assert(same_as, int, 2>, bool>); -template +template constexpr bool test_one(Rng&& rng, Fn func, Expected&& expected_rng) { using ranges::adjacent_transform_view, ranges::adjacent_view, ranges::forward_range, ranges::bidirectional_range, ranges::random_access_range, ranges::sized_range, ranges::common_range, ranges::iterator_t, @@ -86,7 +86,6 @@ constexpr bool test_one(Rng&& rng, Fn func, Expected&& expected_rng) { using R = adjacent_transform_view, N>; static_assert(ranges::view); - static_assert(ranges::input_range); static_assert(forward_range); static_assert(bidirectional_range == bidirectional_range); static_assert(random_access_range == random_access_range); @@ -790,7 +789,7 @@ constexpr bool test_one(Rng&& rng, Fn func, Expected&& expected_rng) { return true; } -template +template constexpr void test_adjacent0(Rng&& rng) { auto func = [] { return 602; }; using Fn = decltype(func); @@ -884,7 +883,7 @@ using test_range = test::ProxyRef{!derived_from}>; struct instantiator { - template + template static constexpr void call() { R r{some_ints}; test_one<1>(r, adjacent1_fn, adjacent1_result); @@ -926,6 +925,60 @@ constexpr void instantiation_test() { #endif // TEST_EVERYTHING } +// LWG-4098 views::adjacent<0> should reject non-forward ranges +template +constexpr void test_input_only(Rng&&, Fn&&) { + if constexpr (!ranges::forward_range) { + static_assert(!CanViewAdjacentTransform); + static_assert(!CanViewAdjacentTransform); + } + + if constexpr (!ranges::forward_range) { + static_assert(!CanViewAdjacentTransform); + static_assert(!CanViewAdjacentTransform); + } +} + +struct input_only_instantiator { +#ifdef TEST_EVERYTHING + template + static constexpr void call() { + R r{some_ints}; + auto nullary_fn = [] { return 1729; }; + test_input_only<0>(r, nullary_fn); + test_input_only<1>(r, adjacent1_fn); + test_input_only<2>(r, pairwise_fn); + test_input_only<4>(r, adjacent4_fn); + test_input_only<7>(r, adjacent7_fn); + } +#else // ^^^ test all input range permutations / test only "interesting" permutations vvv + template + static constexpr void call() { + test_range r{some_ints}; + auto nullary_fn = [] { return 1729; }; + test_input_only<0>(r, nullary_fn); + test_input_only<1>(r, adjacent1_fn); + test_input_only<2>(r, pairwise_fn); + test_input_only<4>(r, adjacent4_fn); + test_input_only<7>(r, adjacent7_fn); + } +#endif // TEST_EVERYTHING +}; + +constexpr void instantiation_input_only_test() { +#ifdef TEST_EVERYTHING + test_in(); +#else // ^^^ test all input range permutations / test only "interesting" permutations vvv + using test::Common, test::Sized; + + // The view is sensitive to category, commonality, and size, but oblivious to proxyness and differencing + input_only_instantiator::call(); + input_only_instantiator::call(); + input_only_instantiator::call(); + input_only_instantiator::call(); +#endif // TEST_EVERYTHING +} + template > using move_only_view = test::range}, test::CanView::yes, @@ -988,4 +1041,7 @@ int main() { static_assert((instantiation_test(), true)); instantiation_test(); + + static_assert((instantiation_input_only_test(), true)); + instantiation_input_only_test(); } diff --git a/tests/std/tests/P2441R2_views_join_with/test.cpp b/tests/std/tests/P2441R2_views_join_with/test.cpp index 0634aa8c1a6..4af69a6c4a8 100644 --- a/tests/std/tests/P2441R2_views_join_with/test.cpp +++ b/tests/std/tests/P2441R2_views_join_with/test.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -674,6 +675,106 @@ void test_lwg3700() { // COMPILE-ONLY static_assert(!CanMemberEnd); } +// LWG-4074 "compatible-joinable-ranges is underconstrained" + +template +struct ValCommon; + +template +struct RefCommon; + +template +struct ValX { + operator ValCommon() const; +}; + +template +struct RefX { + operator ValX() const; + operator RefCommon() const; +}; + +template +struct IterX { + using value_type = ValX; + using difference_type = ptrdiff_t; + + RefX operator*() const; + IterX& operator++(); + IterX operator++(int); + + friend bool operator==(const IterX&, const IterX&); +}; + +template +struct ValY { + operator ValCommon() const; +}; + +template +struct RefY { + operator ValY() const; + operator RefCommon() const; +}; + +template +struct IterY { + using value_type = ValY; + using difference_type = ptrdiff_t; + + RefY operator*() const; + IterY& operator++(); + IterY operator++(int); + + friend bool operator==(const IterY&, const IterY&); +}; + +template +struct ValCommon {}; + +template +struct std::common_type, ValY> { + using type = ValCommon; +}; +template +struct std::common_type, ValX> { + using type = ValCommon; +}; + +template +struct RefCommon { + operator ValCommon() const + requires CanCommonRead; +}; + +template class XQual, template class YQual> + requires convertible_to>, RefCommon> + && convertible_to>, RefCommon> +struct std::basic_common_reference, RefY, XQual, YQual> { + using type = RefCommon; +}; + +template class YQual, template class XQual> + requires convertible_to>, RefCommon> + && convertible_to>, RefCommon> +struct std::basic_common_reference, RefX, YQual, XQual> { + using type = RefCommon; +}; + +static_assert(!CanViewJoinWith>>, ranges::subrange>>); +static_assert(CanViewJoinWith>>, ranges::subrange>>); + +struct NonConstReadableRange { + const ranges::subrange>* begin(); + const ranges::subrange>* end(); + + const ranges::subrange>* begin() const; + const ranges::subrange>* end() const; +}; + +static_assert(CanViewJoinWith>>); +static_assert(!CanViewJoinWith>>); + int main() { { auto filtered_and_joined = diff --git a/tests/std/tests/P2446R2_views_as_rvalue/test.cpp b/tests/std/tests/P2446R2_views_as_rvalue/test.cpp index 0a68c5d8901..3668e8341d7 100644 --- a/tests/std/tests/P2446R2_views_as_rvalue/test.cpp +++ b/tests/std/tests/P2446R2_views_as_rvalue/test.cpp @@ -401,6 +401,17 @@ void test_example_from_p2446r2() { assert(ranges::all_of(words, ranges::empty)); // all strings from words are empty (implementation assumption) } +// LWG-4083 "views::as_rvalue should reject non-input ranges" +struct OutputRvalueIterator { + using difference_type = int; + int operator*() const; + OutputRvalueIterator& operator++(); + void operator++(int); +}; +using OutputRvalueRange = decltype(ranges::subrange{OutputRvalueIterator{}, unreachable_sentinel}); + +static_assert(!CanViewAsRvalue); + int main() { { // Validate views // ... copyable diff --git a/tests/std/tests/P2474R2_views_repeat/test.cpp b/tests/std/tests/P2474R2_views_repeat/test.cpp index 5723478a1c4..00d6d9b3a08 100644 --- a/tests/std/tests/P2474R2_views_repeat/test.cpp +++ b/tests/std/tests/P2474R2_views_repeat/test.cpp @@ -360,16 +360,6 @@ constexpr bool test() { test_iterator_arithmetic(); test_iterator_arithmetic<_Signed128>(); - // GH-4507: LWG-4053 Unary call to std::views::repeat does not decay the argument - { - using RPV = ranges::repeat_view; - - static_assert(same_as); - static_assert(same_as); - static_assert(same_as); - static_assert(same_as); - } - return true; } @@ -380,6 +370,11 @@ static_assert(CanViewRepeat); static_assert( !CanViewRepeat); // _Unsigned128 does not satisfy 'integer-like-with-usable-difference-type' +// Check LWG-4053 "Unary call to std::views::repeat does not decay the argument" (affects CTAD only due to LWG-4054) +static_assert(is_same_v>); +static_assert(is_same_v>); +static_assert(is_same_v>); + // Check LWG-4054 "Repeating a repeat_view should repeat the view" static_assert(is_same_v>>); static_assert(is_same_v>); diff --git a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp index 9a8c5b0da3b..90dd8ab232a 100644 --- a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp @@ -710,7 +710,7 @@ STATIC_ASSERT(__cpp_lib_print == 202207L); STATIC_ASSERT(__cpp_lib_quoted_string_io == 201304L); #if _HAS_CXX23 -STATIC_ASSERT(__cpp_lib_ranges == 202302L); +STATIC_ASSERT(__cpp_lib_ranges == 202406L); #elif _HAS_CXX20 STATIC_ASSERT(__cpp_lib_ranges == 202110L); #elif defined(__cpp_lib_ranges) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 3553aabddd4..73d67273207 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -cmake_minimum_required(VERSION 3.28.0) +cmake_minimum_required(VERSION 3.29.0) project(msvc_standard_libraries_tools LANGUAGES CXX) add_subdirectory(format) diff --git a/tools/format/CMakeLists.txt b/tools/format/CMakeLists.txt index c2371fdaf1c..57c3925b58a 100644 --- a/tools/format/CMakeLists.txt +++ b/tools/format/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -cmake_minimum_required(VERSION 3.28.0) +cmake_minimum_required(VERSION 3.29.0) project(msvc_standard_libraries_format NONE) set(did_search OFF) diff --git a/tools/validate/CMakeLists.txt b/tools/validate/CMakeLists.txt index 332bb225265..2be5cc5fb3b 100644 --- a/tools/validate/CMakeLists.txt +++ b/tools/validate/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -cmake_minimum_required(VERSION 3.28.0) +cmake_minimum_required(VERSION 3.29.0) project(msvc_standard_libraries_validate LANGUAGES CXX) add_executable(validate-binary validate.cpp)