From 297b11d482e00362e75acd0756ec5e9ff890f6c8 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 22 Sep 2023 01:11:39 +0800 Subject: [PATCH 1/5] Fix comparison operators and `get` of `array` Make them correctly handle program-defined specializations. --- stl/inc/array | 41 ++- stl/inc/xutility | 7 + tests/std/test.lst | 1 + .../env.lst | 4 + .../test.cpp | 313 ++++++++++++++++++ 5 files changed, 357 insertions(+), 9 deletions(-) create mode 100644 tests/std/tests/GH_004040_container_nonmember_functions/env.lst create mode 100644 tests/std/tests/GH_004040_container_nonmember_functions/test.cpp diff --git a/stl/inc/array b/stl/inc/array index 7cd41156dbe..634d0c8afd9 100644 --- a/stl/inc/array +++ b/stl/inc/array @@ -775,7 +775,7 @@ _CONSTEXPR20 void swap(array<_Ty, _Size>& _Left, array<_Ty, _Size>& _Right) noex _EXPORT_STD template _NODISCARD _CONSTEXPR20 bool operator==(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { - return _STD equal(_Left._Unchecked_begin(), _Left._Unchecked_end(), _Right._Unchecked_begin()); + return _STD equal(_Left.data(), _Left.data() + _Size, _Right.data()); } #if !_HAS_CXX20 @@ -789,14 +789,13 @@ _NODISCARD bool operator!=(const array<_Ty, _Size>& _Left, const array<_Ty, _Siz _EXPORT_STD template _NODISCARD constexpr _Synth_three_way_result<_Ty> operator<=>( const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { - return _STD lexicographical_compare_three_way(_Left._Unchecked_begin(), _Left._Unchecked_end(), - _Right._Unchecked_begin(), _Right._Unchecked_end(), _Synth_three_way{}); + return _STD lexicographical_compare_three_way( + _Left.data(), _Left.data() + _Size, _Right.data(), _Right.data() + _Size, _Synth_three_way{}); } #else // ^^^ defined(__cpp_lib_concepts) / !defined(__cpp_lib_concepts) vvv template _NODISCARD _CONSTEXPR20 bool operator<(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { - return _STD lexicographical_compare( - _Left._Unchecked_begin(), _Left._Unchecked_end(), _Right._Unchecked_begin(), _Right._Unchecked_end()); + return _STD lexicographical_compare(_Left.data(), _Left.data() + _Size, _Right.data(), _Right.data() + _Size); } template @@ -850,25 +849,49 @@ _NODISCARD constexpr array, _Size> to_array(_Ty (&&_Array)[_Siz _EXPORT_STD template _NODISCARD constexpr _Ty& get(array<_Ty, _Size>& _Arr) noexcept { static_assert(_Idx < _Size, "array index out of bounds"); - return _Arr._Elems[_Idx]; + if constexpr (_Has_unchecked_begin_end>) { + return _Arr._Elems[_Idx]; + } else { +#if _HAS_CXX17 + return _Arr[_Idx]; +#else // ^^^ _HAS_CXX17 / !_HAS_CXX17 vvv + return const_cast<_Ty&>(_STD as_const(_Arr)[_Idx]); +#endif // ^^^ !_HAS_CXX17 ^^^ + } } _EXPORT_STD template _NODISCARD constexpr const _Ty& get(const array<_Ty, _Size>& _Arr) noexcept { static_assert(_Idx < _Size, "array index out of bounds"); - return _Arr._Elems[_Idx]; + if constexpr (_Has_unchecked_begin_end>) { + return _Arr._Elems[_Idx]; + } else { + return _Arr[_Idx]; + } } _EXPORT_STD template _NODISCARD constexpr _Ty&& get(array<_Ty, _Size>&& _Arr) noexcept { static_assert(_Idx < _Size, "array index out of bounds"); - return _STD move(_Arr._Elems[_Idx]); + if constexpr (_Has_unchecked_begin_end>) { + return _STD move(_Arr._Elems[_Idx]); + } else { +#if _HAS_CXX17 + return _STD move(_Arr[_Idx]); +#else // ^^^ _HAS_CXX17 / !_HAS_CXX17 vvv + return const_cast<_Ty&&>(_STD move(_STD as_const(_Arr)[_Idx])); +#endif // ^^^ !_HAS_CXX17 ^^^ + } } _EXPORT_STD template _NODISCARD constexpr const _Ty&& get(const array<_Ty, _Size>&& _Arr) noexcept { static_assert(_Idx < _Size, "array index out of bounds"); - return _STD move(_Arr._Elems[_Idx]); + if constexpr (_Has_unchecked_begin_end>) { + return _STD move(_Arr._Elems[_Idx]); + } else { + return _STD move(_Arr[_Idx]); + } } #if _HAS_TR1_NAMESPACE diff --git a/stl/inc/xutility b/stl/inc/xutility index 880293a0d71..2e0d8374828 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -582,6 +582,13 @@ struct _Unused_parameter { // generic unused parameter struct constexpr _Unused_parameter(_Ty&&) noexcept {} }; +template // checks whether a container/view is a non-customized specialization +_INLINE_VAR constexpr bool _Has_unchecked_begin_end = false; + +template +_INLINE_VAR constexpr bool _Has_unchecked_begin_end<_Ty, + void_t()._Unchecked_begin()), decltype(_STD declval<_Ty&>()._Unchecked_end())>> = true; + template using _Algorithm_int_t = conditional_t, _Ty, ptrdiff_t>; diff --git a/tests/std/test.lst b/tests/std/test.lst index e493dcb6540..3b693b30f45 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -231,6 +231,7 @@ tests\GH_003676_format_large_hh_mm_ss_values tests\GH_003735_char_traits_signatures tests\GH_003840_tellg_when_reading_lf_file_in_text_mode tests\GH_003867_output_nan +tests\GH_004040_container_nonmember_functions tests\LWG2381_num_get_floating_point tests\LWG2597_complex_branch_cut tests\LWG3018_shared_ptr_function diff --git a/tests/std/tests/GH_004040_container_nonmember_functions/env.lst b/tests/std/tests/GH_004040_container_nonmember_functions/env.lst new file mode 100644 index 00000000000..19f025bd0e6 --- /dev/null +++ b/tests/std/tests/GH_004040_container_nonmember_functions/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_matrix.lst diff --git a/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp b/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp new file mode 100644 index 00000000000..4ec9ac6b373 --- /dev/null +++ b/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp @@ -0,0 +1,313 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include +#include +#include +#include +#include + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +#if _HAS_CXX20 +#define CONSTEXPR20 constexpr +#define CONSTEXPR17 constexpr +#define NODISCARD20 [[nodiscard]] +#elif _HAS_CXX17 // ^^^ _HAS_CXX20 / !_HAS_CXX20 && _HAS_CXX17 vvv +#define CONSTEXPR20 inline +#define CONSTEXPR17 constexpr +#define NODISCARD20 +#else // ^^^ !_HAS_CXX20 && _HAS_CXX17 / !_HAS_CXX17 vvv +#define CONSTEXPR20 inline +#define CONSTEXPR17 inline +#define NODISCARD20 +#endif // ^^^ !_HAS_CXX17 ^^^ + +using namespace std; + +struct Foo { +#if _HAS_CXX20 + friend constexpr auto operator<=>(Foo, Foo) = default; +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv + friend constexpr bool operator==(Foo, Foo) noexcept { + return true; + } + + friend constexpr bool operator!=(Foo, Foo) noexcept { + return false; + } + + friend constexpr bool operator<(Foo, Foo) noexcept { + return false; + } + + friend constexpr bool operator>(Foo, Foo) noexcept { + return false; + } + + friend constexpr bool operator<=(Foo, Foo) noexcept { + return true; + } + + friend constexpr bool operator>=(Foo, Foo) noexcept { + return true; + } +#endif // ^^^ !_HAS_CXX20 ^^^ +}; + +template +struct std::array { + using value_type = Foo; + using pointer = Foo*; + using const_pointer = const Foo*; + using reference = Foo&; + using const_reference = const Foo&; + using size_type = size_t; + using difference_type = ptrdiff_t; + using iterator = Foo*; + using const_iterator = const Foo*; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + CONSTEXPR20 void fill(const Foo&) {} // Foo is no-op assignable. + CONSTEXPR20 void swap(array&) noexcept {} // Foo is no-op swappable. + + CONSTEXPR17 iterator begin() noexcept { + return elems_; + } + CONSTEXPR17 const_iterator begin() const noexcept { + return elems_; + } + CONSTEXPR17 iterator end() noexcept { + return elems_ + N; + } + CONSTEXPR17 const_iterator end() const noexcept { + return elems_ + N; + } + + CONSTEXPR17 reverse_iterator rbegin() noexcept { + return reverse_iterator{elems_ + N}; + } + CONSTEXPR17 const_reverse_iterator rbegin() const noexcept { + return const_reverse_iterator{elems_ + N}; + } + CONSTEXPR17 reverse_iterator rend() noexcept { + return reverse_iterator{elems_}; + } + CONSTEXPR17 const_reverse_iterator rend() const noexcept { + return const_reverse_iterator{elems_}; + } + + CONSTEXPR17 const_iterator cbegin() const noexcept { + return elems_; + } + CONSTEXPR17 const_iterator cend() const noexcept { + return elems_ + N; + } + CONSTEXPR17 const_reverse_iterator crbegin() const noexcept { + return const_reverse_iterator{elems_ + N}; + } + CONSTEXPR17 const_reverse_iterator crend() const noexcept { + return const_reverse_iterator{elems_}; + } + + NODISCARD20 constexpr bool empty() const noexcept { + return false; + } + constexpr size_type size() const noexcept { + return N; + } + constexpr size_type max_size() const noexcept { + return N; + } + + CONSTEXPR17 reference operator[](size_type n) { + return elems_[n]; + } + constexpr const_reference operator[](size_type n) const { + return elems_[n]; + } + CONSTEXPR17 reference at(size_type n) { + return n < N ? elems_[n] : throw out_of_range{"bad array access"}; + } + constexpr const_reference at(size_type n) const { + return n < N ? elems_[n] : throw out_of_range{"bad array access"}; + } + CONSTEXPR17 reference front() { + return elems_[0]; + } + constexpr const_reference front() const { + return elems_[0]; + } + CONSTEXPR17 reference back() { + return elems_[N - 1]; + } + constexpr const_reference back() const { + return elems_[N - 1]; + } + + CONSTEXPR17 pointer data() noexcept { + return elems_; + } + CONSTEXPR17 const_pointer data() const noexcept { + return elems_; + } + + Foo elems_[N]; +}; + +template <> +struct std::array { + using value_type = Foo; + using pointer = Foo*; + using const_pointer = const Foo*; + using reference = Foo&; + using const_reference = const Foo&; + using size_type = size_t; + using difference_type = ptrdiff_t; + using iterator = Foo*; + using const_iterator = const Foo*; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + CONSTEXPR20 void fill(const Foo&) {} // Foo is no-op assignable. + CONSTEXPR20 void swap(array&) noexcept {} // Foo is no-op swappable. + + CONSTEXPR17 iterator begin() noexcept { + return nullptr; + } + CONSTEXPR17 const_iterator begin() const noexcept { + return nullptr; + } + CONSTEXPR17 iterator end() noexcept { + return nullptr; + } + CONSTEXPR17 const_iterator end() const noexcept { + return nullptr; + } + + CONSTEXPR17 reverse_iterator rbegin() noexcept { + return reverse_iterator{end()}; + } + CONSTEXPR17 const_reverse_iterator rbegin() const noexcept { + return const_reverse_iterator{end()}; + } + CONSTEXPR17 reverse_iterator rend() noexcept { + return reverse_iterator{begin()}; + } + CONSTEXPR17 const_reverse_iterator rend() const noexcept { + return const_reverse_iterator{begin()}; + } + + CONSTEXPR17 const_iterator cbegin() const noexcept { + return nullptr; + } + CONSTEXPR17 const_iterator cend() const noexcept { + return nullptr; + } + CONSTEXPR17 const_reverse_iterator crbegin() const noexcept { + return const_reverse_iterator{end()}; + } + CONSTEXPR17 const_reverse_iterator crend() const noexcept { + return const_reverse_iterator{begin()}; + } + + NODISCARD20 constexpr bool empty() const noexcept { + return true; + } + constexpr size_type size() const noexcept { + return 0; + } + constexpr size_type max_size() const noexcept { + return 0; + } + + // Perhaps these functions of array shouldn't be constexpr as an invocation is always throwing or UB. + reference operator[](size_type) { + abort(); // UB + } + const_reference operator[](size_type) const { + abort(); // UB + } + reference at(size_type) { + throw out_of_range{"bad array access"}; + } + const_reference at(size_type) const { + throw out_of_range{"bad array access"}; + } + reference front() { + abort(); // UB + } + const_reference front() const { + abort(); // UB + } + reference back() { + abort(); // UB + } + const_reference back() const { + abort(); // UB + } + + CONSTEXPR17 pointer data() noexcept { + return nullptr; + } + CONSTEXPR17 const_pointer data() const noexcept { + return nullptr; + } + + unsigned char dummy_[1]; +}; + +constexpr bool test_array_get() { + array a{}; + const auto& cref = a; + + STATIC_ASSERT(is_same_v(a)), Foo&>); + STATIC_ASSERT(is_same_v(cref)), const Foo&>); + STATIC_ASSERT(is_same_v(move(a))), Foo&&>); + STATIC_ASSERT(is_same_v(move(cref))), const Foo&&>); + + assert(get<0>(a) == Foo{}); + assert(get<0>(cref) == Foo{}); + assert(get<0>(move(a)) == Foo{}); + assert(get<0>(move(cref)) == Foo{}); + + return true; +} + +CONSTEXPR20 bool test_array_comparison() { + using A0 = array; + assert(A0{} == A0{}); + assert(!(A0{} != A0{})); + assert(!(A0{} < A0{})); + assert(!(A0{} > A0{})); + assert(A0{} <= A0{}); + assert(A0{} >= A0{}); +#if _HAS_CXX20 + assert(A0{} <=> A0{} == strong_ordering::equal); +#endif // _HAS_CXX20 + + using A1 = array; + assert(A1{} == A1{}); + assert(!(A1{} != A1{})); + assert(!(A1{} < A1{})); + assert(!(A1{} > A1{})); + assert(A1{} <= A1{}); + assert(A1{} >= A1{}); +#if _HAS_CXX20 + assert(A1{} <=> A1{} == strong_ordering::equal); +#endif // _HAS_CXX20 + + return true; +} + +int main() { + test_array_get(); + STATIC_ASSERT(test_array_get()); + test_array_comparison(); +#if _HAS_CXX20 + static_assert(test_array_comparison()); +#endif // _HAS_CXX20 +} From cfb79ea066fc8fe62bdf36653b2a126abb10ff72 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 22 Sep 2023 01:38:08 +0800 Subject: [PATCH 2/5] Oops, EDG! --- .../GH_004040_container_nonmember_functions/test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp b/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp index 4ec9ac6b373..ac539fe7abc 100644 --- a/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp +++ b/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp @@ -285,9 +285,9 @@ CONSTEXPR20 bool test_array_comparison() { assert(!(A0{} > A0{})); assert(A0{} <= A0{}); assert(A0{} >= A0{}); -#if _HAS_CXX20 +#if _HAS_CXX20 && defined(__cpp_lib_concepts) // TRANSITION, GH-395 assert(A0{} <=> A0{} == strong_ordering::equal); -#endif // _HAS_CXX20 +#endif // _HAS_CXX20 && defined(__cpp_lib_concepts) using A1 = array; assert(A1{} == A1{}); @@ -296,9 +296,9 @@ CONSTEXPR20 bool test_array_comparison() { assert(!(A1{} > A1{})); assert(A1{} <= A1{}); assert(A1{} >= A1{}); -#if _HAS_CXX20 +#if _HAS_CXX20 && defined(__cpp_lib_concepts) // TRANSITION, GH-395 assert(A1{} <=> A1{} == strong_ordering::equal); -#endif // _HAS_CXX20 +#endif // _HAS_CXX20 && defined(__cpp_lib_concepts) return true; } From 0c96610cd4e324949d4d4926fe775beba734cb9f Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 21 Sep 2023 16:58:16 -0700 Subject: [PATCH 3/5] Rename to `Meow`. --- .../test.cpp | 96 +++++++++---------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp b/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp index ac539fe7abc..8b739020cc3 100644 --- a/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp +++ b/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp @@ -27,52 +27,52 @@ using namespace std; -struct Foo { +struct Meow { #if _HAS_CXX20 - friend constexpr auto operator<=>(Foo, Foo) = default; + friend constexpr auto operator<=>(Meow, Meow) = default; #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv - friend constexpr bool operator==(Foo, Foo) noexcept { + friend constexpr bool operator==(Meow, Meow) noexcept { return true; } - friend constexpr bool operator!=(Foo, Foo) noexcept { + friend constexpr bool operator!=(Meow, Meow) noexcept { return false; } - friend constexpr bool operator<(Foo, Foo) noexcept { + friend constexpr bool operator<(Meow, Meow) noexcept { return false; } - friend constexpr bool operator>(Foo, Foo) noexcept { + friend constexpr bool operator>(Meow, Meow) noexcept { return false; } - friend constexpr bool operator<=(Foo, Foo) noexcept { + friend constexpr bool operator<=(Meow, Meow) noexcept { return true; } - friend constexpr bool operator>=(Foo, Foo) noexcept { + friend constexpr bool operator>=(Meow, Meow) noexcept { return true; } #endif // ^^^ !_HAS_CXX20 ^^^ }; template -struct std::array { - using value_type = Foo; - using pointer = Foo*; - using const_pointer = const Foo*; - using reference = Foo&; - using const_reference = const Foo&; +struct std::array { + using value_type = Meow; + using pointer = Meow*; + using const_pointer = const Meow*; + using reference = Meow&; + using const_reference = const Meow&; using size_type = size_t; using difference_type = ptrdiff_t; - using iterator = Foo*; - using const_iterator = const Foo*; - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; + using iterator = Meow*; + using const_iterator = const Meow*; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; - CONSTEXPR20 void fill(const Foo&) {} // Foo is no-op assignable. - CONSTEXPR20 void swap(array&) noexcept {} // Foo is no-op swappable. + CONSTEXPR20 void fill(const Meow&) {} // Meow is no-op assignable. + CONSTEXPR20 void swap(array&) noexcept {} // Meow is no-op swappable. CONSTEXPR17 iterator begin() noexcept { return elems_; @@ -130,10 +130,10 @@ struct std::array { return elems_[n]; } CONSTEXPR17 reference at(size_type n) { - return n < N ? elems_[n] : throw out_of_range{"bad array access"}; + return n < N ? elems_[n] : throw out_of_range{"bad array access"}; } constexpr const_reference at(size_type n) const { - return n < N ? elems_[n] : throw out_of_range{"bad array access"}; + return n < N ? elems_[n] : throw out_of_range{"bad array access"}; } CONSTEXPR17 reference front() { return elems_[0]; @@ -155,25 +155,25 @@ struct std::array { return elems_; } - Foo elems_[N]; + Meow elems_[N]; }; template <> -struct std::array { - using value_type = Foo; - using pointer = Foo*; - using const_pointer = const Foo*; - using reference = Foo&; - using const_reference = const Foo&; +struct std::array { + using value_type = Meow; + using pointer = Meow*; + using const_pointer = const Meow*; + using reference = Meow&; + using const_reference = const Meow&; using size_type = size_t; using difference_type = ptrdiff_t; - using iterator = Foo*; - using const_iterator = const Foo*; - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; + using iterator = Meow*; + using const_iterator = const Meow*; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; - CONSTEXPR20 void fill(const Foo&) {} // Foo is no-op assignable. - CONSTEXPR20 void swap(array&) noexcept {} // Foo is no-op swappable. + CONSTEXPR20 void fill(const Meow&) {} // Meow is no-op assignable. + CONSTEXPR20 void swap(array&) noexcept {} // Meow is no-op swappable. CONSTEXPR17 iterator begin() noexcept { return nullptr; @@ -232,10 +232,10 @@ struct std::array { abort(); // UB } reference at(size_type) { - throw out_of_range{"bad array access"}; + throw out_of_range{"bad array access"}; } const_reference at(size_type) const { - throw out_of_range{"bad array access"}; + throw out_of_range{"bad array access"}; } reference front() { abort(); // UB @@ -261,24 +261,24 @@ struct std::array { }; constexpr bool test_array_get() { - array a{}; + array a{}; const auto& cref = a; - STATIC_ASSERT(is_same_v(a)), Foo&>); - STATIC_ASSERT(is_same_v(cref)), const Foo&>); - STATIC_ASSERT(is_same_v(move(a))), Foo&&>); - STATIC_ASSERT(is_same_v(move(cref))), const Foo&&>); + STATIC_ASSERT(is_same_v(a)), Meow&>); + STATIC_ASSERT(is_same_v(cref)), const Meow&>); + STATIC_ASSERT(is_same_v(move(a))), Meow&&>); + STATIC_ASSERT(is_same_v(move(cref))), const Meow&&>); - assert(get<0>(a) == Foo{}); - assert(get<0>(cref) == Foo{}); - assert(get<0>(move(a)) == Foo{}); - assert(get<0>(move(cref)) == Foo{}); + assert(get<0>(a) == Meow{}); + assert(get<0>(cref) == Meow{}); + assert(get<0>(move(a)) == Meow{}); + assert(get<0>(move(cref)) == Meow{}); return true; } CONSTEXPR20 bool test_array_comparison() { - using A0 = array; + using A0 = array; assert(A0{} == A0{}); assert(!(A0{} != A0{})); assert(!(A0{} < A0{})); @@ -289,7 +289,7 @@ CONSTEXPR20 bool test_array_comparison() { assert(A0{} <=> A0{} == strong_ordering::equal); #endif // _HAS_CXX20 && defined(__cpp_lib_concepts) - using A1 = array; + using A1 = array; assert(A1{} == A1{}); assert(!(A1{} != A1{})); assert(!(A1{} < A1{})); From e2aeda03e99fd6fd7f5b049d88b27109c6092ff2 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 21 Sep 2023 16:59:25 -0700 Subject: [PATCH 4/5] Avoid shadowing: `cref` => `c` --- .../GH_004040_container_nonmember_functions/test.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp b/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp index 8b739020cc3..7e3b19d25bf 100644 --- a/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp +++ b/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp @@ -262,17 +262,17 @@ struct std::array { constexpr bool test_array_get() { array a{}; - const auto& cref = a; + const auto& c = a; STATIC_ASSERT(is_same_v(a)), Meow&>); - STATIC_ASSERT(is_same_v(cref)), const Meow&>); + STATIC_ASSERT(is_same_v(c)), const Meow&>); STATIC_ASSERT(is_same_v(move(a))), Meow&&>); - STATIC_ASSERT(is_same_v(move(cref))), const Meow&&>); + STATIC_ASSERT(is_same_v(move(c))), const Meow&&>); assert(get<0>(a) == Meow{}); - assert(get<0>(cref) == Meow{}); + assert(get<0>(c) == Meow{}); assert(get<0>(move(a)) == Meow{}); - assert(get<0>(move(cref)) == Meow{}); + assert(get<0>(move(c)) == Meow{}); return true; } From 30611251d95d9021e2bfad0bf4528fe70da66307 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 21 Sep 2023 16:59:57 -0700 Subject: [PATCH 5/5] Include ``. --- tests/std/tests/GH_004040_container_nonmember_functions/test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp b/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp index 7e3b19d25bf..25c53023fa0 100644 --- a/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp +++ b/tests/std/tests/GH_004040_container_nonmember_functions/test.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)