diff --git a/stl/inc/array b/stl/inc/array index b5231133eb..454b4bb9ac 100644 --- a/stl/inc/array +++ b/stl/inc/array @@ -380,32 +380,32 @@ void swap(array<_Ty, _Size>& _Left, array<_Ty, _Size>& _Right) noexcept(noexcept } template -_NODISCARD bool operator==(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { +_NODISCARD _CONSTEXPR20 bool operator==(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { return _STD equal(_Left.begin(), _Left.end(), _Right.begin()); } template -_NODISCARD bool operator!=(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { +_NODISCARD _CONSTEXPR20 bool operator!=(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { return !(_Left == _Right); } template -_NODISCARD bool operator<(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { +_NODISCARD _CONSTEXPR20 bool operator<(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { return _STD lexicographical_compare(_Left.begin(), _Left.end(), _Right.begin(), _Right.end()); } template -_NODISCARD bool operator>(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { +_NODISCARD _CONSTEXPR20 bool operator>(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { return _Right < _Left; } template -_NODISCARD bool operator<=(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { +_NODISCARD _CONSTEXPR20 bool operator<=(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { return !(_Right < _Left); } template -_NODISCARD bool operator>=(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { +_NODISCARD _CONSTEXPR20 bool operator>=(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { return !(_Left < _Right); } diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index df4c26e2ff..90e6c4a6f6 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -169,6 +169,7 @@ // P0919R3 Heterogeneous Lookup For Unordered Containers // P0966R1 string::reserve() Should Not Shrink // P1006R1 constexpr For pointer_traits::pointer_to() +// P1023R0 constexpr For std::array Comparisons // P1024R3 Enhancing span Usability // P1085R2 Removing span Comparisons // P1115R3 erase()/erase_if() Return size_type @@ -1037,7 +1038,6 @@ #if _HAS_CXX17 #define __cpp_lib_any 201606L #define __cpp_lib_apply 201603L -#define __cpp_lib_array_constexpr 201803L #define __cpp_lib_atomic_is_always_lock_free 201603L #define __cpp_lib_boyer_moore_searcher 201603L #if _HAS_STD_BYTE @@ -1127,6 +1127,12 @@ #define __cpp_lib_unwrap_ref 201811L #endif // _HAS_CXX20 +#if _HAS_CXX20 +#define __cpp_lib_array_constexpr 201806L // P1023R0 constexpr For std::array Comparisons +#elif _HAS_CXX17 // ^^^ _HAS_CXX20 / _HAS_CXX17 vvv +#define __cpp_lib_array_constexpr 201803L +#endif // _HAS_CXX17 + // EXPERIMENTAL #define __cpp_lib_experimental_erase_if 201411L #define __cpp_lib_experimental_filesystem 201406L diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 39a88e4913..f33c5812de 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -452,9 +452,6 @@ std/language.support/support.limits/support.limits.general/functional.version.pa std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp SKIP std/language.support/support.limits/support.limits.general/memory.version.pass.cpp SKIP -# C++20 P1023R0 "constexpr For std::array Comparisons" -std/containers/sequences/array/compare.pass.cpp SKIP - # C++20 P1032R1 "Miscellaneous constexpr" std/language.support/support.limits/support.limits.general/array.version.pass.cpp SKIP std/language.support/support.limits/support.limits.general/functional.version.pass.cpp SKIP diff --git a/tests/libcxx/skipped_tests.txt b/tests/libcxx/skipped_tests.txt index 27551a8179..5054a73875 100644 --- a/tests/libcxx/skipped_tests.txt +++ b/tests/libcxx/skipped_tests.txt @@ -452,9 +452,6 @@ language.support\support.limits\support.limits.general\functional.version.pass.c language.support\support.limits\support.limits.general\iterator.version.pass.cpp language.support\support.limits\support.limits.general\memory.version.pass.cpp -# C++20 P1023R0 "constexpr For std::array Comparisons" -containers\sequences\array\compare.pass.cpp - # C++20 P1032R1 "Miscellaneous constexpr" language.support\support.limits\support.limits.general\array.version.pass.cpp language.support\support.limits\support.limits.general\functional.version.pass.cpp diff --git a/tests/std/test.lst b/tests/std/test.lst index a0143a61b5..6d2945178b 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -249,6 +249,7 @@ tests\P0898R3_concepts tests\P0898R3_identity tests\P0919R3_heterogeneous_unordered_lookup tests\P0966R1_string_reserve_should_not_shrink +tests\P1023R0_constexpr_for_array_comparisons tests\P1165R1_consistently_propagating_stateful_allocators tests\P1423R3_char8_t_remediation tests\P1645R1_constexpr_numeric diff --git a/tests/std/tests/P1023R0_constexpr_for_array_comparisons/env.lst b/tests/std/tests/P1023R0_constexpr_for_array_comparisons/env.lst new file mode 100644 index 0000000000..642f530ffa --- /dev/null +++ b/tests/std/tests/P1023R0_constexpr_for_array_comparisons/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_latest_matrix.lst diff --git a/tests/std/tests/P1023R0_constexpr_for_array_comparisons/test.cpp b/tests/std/tests/P1023R0_constexpr_for_array_comparisons/test.cpp new file mode 100644 index 0000000000..f495194b33 --- /dev/null +++ b/tests/std/tests/P1023R0_constexpr_for_array_comparisons/test.cpp @@ -0,0 +1,71 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include + +using namespace std; + +constexpr array a0{{2, 8, 9, 1, 9}}; +constexpr array a1{{2, 8, 9}}; +constexpr array a2{{2, 8, 9, 1, 8}}; +constexpr array a3{}; + +constexpr void test_operator_eq() { + assert(a0 == a0); + assert(a1 == a1); + assert(!(a0 == a2)); + assert(a3 == a3); +} + +constexpr void test_operator_neq() { + assert(!(a0 != a0)); + assert(!(a1 != a1)); + assert(a0 != a2); + assert(!(a3 != a3)); +} + +constexpr void test_operator_lt() { + assert(!(a0 < a0)); + assert(!(a1 < a1)); + assert(a2 < a0); + assert(!(a3 < a3)); +} + +constexpr void test_operator_gt() { + assert(!(a0 > a0)); + assert(!(a1 > a1)); + assert(a0 > a2); + assert(!(a3 > a3)); +} + + +constexpr void test_operator_leq() { + assert(a0 <= a0); + assert(a1 <= a1); + assert(a2 <= a0); + assert(a3 <= a3); +} + + +constexpr void test_operator_geq() { + assert(a0 >= a0); + assert(a1 >= a1); + assert(a0 >= a2); + assert(a3 >= a3); +} + +constexpr bool test() { + test_operator_eq(); + test_operator_neq(); + test_operator_lt(); + test_operator_gt(); + test_operator_leq(); + test_operator_geq(); + return true; +} + +int main() { + test(); + static_assert(test()); +} diff --git a/tests/std/tests/VSO_0157762_feature_test_macros/test.cpp b/tests/std/tests/VSO_0157762_feature_test_macros/test.cpp index 21471a8abb..2a7a4f5afc 100644 --- a/tests/std/tests/VSO_0157762_feature_test_macros/test.cpp +++ b/tests/std/tests/VSO_0157762_feature_test_macros/test.cpp @@ -718,7 +718,15 @@ STATIC_ASSERT(__cpp_lib_apply == 201603L); #endif #endif -#if _HAS_CXX17 +#if _HAS_CXX20 +#ifndef __cpp_lib_array_constexpr +#error __cpp_lib_array_constexpr is not defined +#elif __cpp_lib_array_constexpr != 201806L +#error __cpp_lib_array_constexpr is not 201806L +#else +STATIC_ASSERT(__cpp_lib_array_constexpr == 201806L); +#endif +#elif _HAS_CXX17 #ifndef __cpp_lib_array_constexpr #error __cpp_lib_array_constexpr is not defined #elif __cpp_lib_array_constexpr != 201803L